socket()系统调用,带有三个参数:
1、参数domain指明通信域,如PF_UNIX(unix域),PF_INET(IPv4),
PF_INET6(IPv6)等
2、type指明通信类型,最常用的如SOCK_STREAM(面向连接可靠方式,
比如TCP)、SOCK_DGRAM(非面向连接的非可靠方式,比如UDP)等。
3、参数protocol指定需要使用的协议。虽然可以对同一个协议
家族(protocol family)(或者说通信域(domain))指定不同的协议
参数,但是通常只有一个。对于TCP参数可指定为IPPROTO_TCP,对于
UDP可以用IPPROTO_UDP。你不必显式制定这个参数,使用0则根据前
两个参数使用默认的协议。
sa:SOCKADDR_IN;
sa.sin_family:=PF_INET;
sa.sin_port:=htons(lisport);
sa.sin_addr.S_addr:=INADDR_ANY;//---------dcc-----htonl(INADDR_ANY); //INADDR_ANY,表示本地计算机的默认IP地址
salen:=sizeof(sa);
//******************************************************************************
{ sin_family指代协议族,在socket编程中只能是AF_INET ,PF_INET
sin_port存储端口号(使用网络字节顺序)
sin_addr存储IP地址,使用in_addr这个数据结构
s_addr按照网络字节顺序存储IP地址
sin_zero是为了让sockaddr与sockaddr_in两个数据结构保持大小相同而保留的空字节。
}
int bind ( SOCKET s , const struct sockaddr FAR *addr , int namelen );
[参数]
s - 指向用Socket函数生成的Socket Descrīptor
addr - 指向Socket地址的指针
namelen - 该地址的长度.
[返回值]
当函数成功调用时返回0
调用失败时返回 SOCKET_ERROR
if bind(lissocket,sa,sizeof(sa))=SOCKET_ERROR then
begin
closesocket(lissocket);
DebugMessage('无法打开端口:'+inttostr(lisport));
exit;
end;
listen(lissocket,200);
//**********************************************
{socket 套接字,网络编程必用的
listen ()监听从服务器传来的接收数据
listen ()创建一个套接口并监听申请的连接.}
//*******************************************
accept()
acceptsocket:=accept(lissocket,@sa,@salen); //AcceptSocket 是一个阻塞方法,它返回可用来发送和接收数据的 Socket。
DebugMessage('连接成功!');
if acceptsocket=INVALID_SOCKET then
begin
DebugMessage('接受Socket失败!');
continue;
end;
//**************&&&&&&&&&&&&&&&&&&%%%%%%%%%%%%%%%%%%%%%%%% 源码
unit Listenthread;
interface
uses
Classes,messages,windows,winsock,stdctrls,Sysutils;
type
//线程的声明
TListenThread = class(TThread)
private
{ Private declarations }
lissocket:Tsocket;
lisport:integer;
str:string;
procedure AddMes;
procedure DebugMessage(mes:string);
protected
procedure Execute; override; //线程执行过程
public
constructor CreateIt(port:integer); //创建线程端口
destructor destroy;override; //结束线程
end;
implementation
uses main,UnitSocketRead,DataUnit ;
//监听线程的构造方法
constructor TlistenThread.CreateIt(port:integer); //创建端口
begin
inherited create(true);
lisport:=port;
FreeOnTerminate:=true;
resume; //******唤醒线程 重(新)开(始),再继续;恢复;收回;【微软】继续执行 挂起的线程重新执行。
end;
destructor TlistenThread.destroy;
begin
if lissocket<>INVALID_SOCKET then
begin
//shutdown(lissocket,SD_BOTH);//中断连接,其实连接还存在。
closesocket(lissocket); //*********CloseSocket() 是用来关闭一个 Socket 的!
DebugMessage('Close Socket');
end;
inherited destroy;
end;
procedure TlistenThread.Execute;
var acceptsocket:Tsocket;
sa:SOCKADDR_IN;
salen:integer;
tempthreadread:ThreadSocketRead;
begin
{ Place thread code here }
Lissocket:=socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
//***********************************************************************************
{socket()系统调用,带有三个参数:
1、参数domain指明通信域,如PF_UNIX(unix域),PF_INET(IPv4),
PF_INET6(IPv6)等
2、type指明通信类型,最常用的如SOCK_STREAM(面向连接可靠方式,
比如TCP)、SOCK_DGRAM(非面向连接的非可靠方式,比如UDP)等。
3、参数protocol指定需要使用的协议。虽然可以对同一个协议
家族(protocol family)(或者说通信域(domain))指定不同的协议
参数,但是通常只有一个。对于TCP参数可指定为IPPROTO_TCP,对于
UDP可以用IPPROTO_UDP。你不必显式制定这个参数,使用0则根据前
两个参数使用默认的协议。}
//******************************************************************************
if lissocket=INVALID_SOCKET then
begin
DebugMessage('Create Socket Error');
exit;
end;
DebugMessage('Create Socket!'); //调用本单元的 DebugMessage方法 显示成功创建套接字
sa.sin_family:=PF_INET;
sa.sin_port:=htons(lisport);
sa.sin_addr.S_addr:=INADDR_ANY;//---------dcc-----htonl(INADDR_ANY); //INADDR_ANY,表示本地计算机的默认IP地址
salen:=sizeof(sa);
//******************************************************************************
{ sin_family指代协议族,在socket编程中只能是AF_INET ,PF_INET
sin_port存储端口号(使用网络字节顺序)
sin_addr存储IP地址,使用in_addr这个数据结构
s_addr按照网络字节顺序存储IP地址
sin_zero是为了让sockaddr与sockaddr_in两个数据结构保持大小相同而保留的空字节。
}
{ int bind ( SOCKET s , const struct sockaddr FAR *addr , int namelen );
[参数]
s - 指向用Socket函数生成的Socket Descrīptor
addr - 指向Socket地址的指针
namelen - 该地址的长度.
[返回值]
当函数成功调用时返回0
调用失败时返回 SOCKET_ERROR
}
//***********************************************************************************
if bind(lissocket,sa,sizeof(sa))=SOCKET_ERROR then
begin
closesocket(lissocket);
DebugMessage('无法打开端口:'+inttostr(lisport));
exit;
end;
DebugMessage('listen on port:'+inttostr(lisport)); //调用本单元的 DebugMessage方法 显示连接的端口号
listen(lissocket,200);
//**********************************************
{socket 套接字,网络编程必用的
listen ()监听从服务器传来的接收数据
listen ()创建一个套接口并监听申请的连接.}
//*******************************************
while not terminated do
begin
acceptsocket:=accept(lissocket,@sa,@salen); //AcceptSocket 是一个阻塞方法,它返回可用来发送和接收数据的 Socket。
DebugMessage('连接成功!');
if acceptsocket=INVALID_SOCKET then
begin
DebugMessage('接受Socket失败!');
continue;
end;
//调用 UnitSocketRead 方法块中的 ThreadSocketRead.CreateIt 方法 并且同时调用datamoudle的数据库连接控件的连接语句。
tempthreadread:=ThreadSocketRead.CreateIt(acceptsocket,Datamodule1.ADOConnection1.ConnectionString);
if tempthreadread<>nil then
begin
str:='New thread:'+IntToStr(tempthreadread.threadid);
synchronize(AddMes); //synchronize 时间同步 调用方法本模块的 AddMes方法
end
else
begin
closesocket(acceptsocket);
DebugMessage('创建执行线程失败!'); //调用本单元的 DebugMessage方法
end;
end;
closesocket(lissocket); //一个关闭套接口的方法
end;
procedure TlistenThread.AddMes; //显示当前的时间 和 要显示的信息
begin
if not terminated then //terminated 终结
FormMain.Memo.Lines.Add(FormatDatetime('hh:mm:ss',Now)+'-*-'+Str);
end;
procedure TListenThread.DebugMessage(mes:string); //获得要显示的信息 并将信息作为参数传递给AddMes方法
begin
if gdebug then
begin
Str:=mes;
synchronize(AddMes); //synchronize 时间同步 调用方法本模块的 AddMes方法
end;
end;
end.