在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
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.
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论