onlyou13

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

    WSAEventSelect类似于WSAAsycnSelect,区别就是当Socket上有“事件”时,传递一个Event而不是Windows消息。

  1 unit Unit1;  
  2   
  3 interface  
  4   
  5 uses  
  6   WinSock2, Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  
  7   Dialogs, StdCtrls, ExtCtrls;  
  8   
  9 type  
 10   TWorkThread = class(TThread)  
 11   private  
 12     FMemo: TMemo;  
 13     FBuff: array [0..10] of Char;  
 14     procedure ShowRecv;  
 15   protected  
 16     procedure Execute;override;  
 17   public  
 18     constructor Create(Memo: TMemo);  
 19   end;  
 20   
 21   TForm1 = class(TForm)  
 22     Memo1: TMemo;  
 23     procedure FormCreate(Sender: TObject);  
 24   private  
 25     { Private declarations }  
 26   public  
 27     { Public declarations }  
 28   end;  
 29   
 30 var  
 31   Form1: TForm1;  
 32   
 33 implementation  
 34   
 35 {$R *.dfm}  
 36   
 37 { TWorkThread }  
 38   
 39 constructor TWorkThread.Create(Memo: TMemo);  
 40 begin  
 41   inherited Create(False);  
 42   
 43   FMemo:= Memo;  
 44 end;  
 45   
 46 procedure TWorkThread.Execute;  
 47 var  
 48   WSData: TWSAData;  
 49   LocalAddr: TSockAddrIn;  
 50   ClientAddr: TSockAddrIn;  
 51   ClientAddrLen: Integer;  
 52   ServerSocket: TSocket;  
 53   ClientSocket: TSocket;  
 54   WSAEventObject: WSAEvent;  
 55   Idx: DWORD;  
 56   EventTotal: DWORD;  
 57   SocketArray: array [0..WSA_MAXIMUM_WAIT_EVENTS - 1] of TSocket;  
 58   WSAEventArray: array [0..WSA_MAXIMUM_WAIT_EVENTS - 1] of WSAEvent;  
 59   WSANetEvents: TWSANetworkEvents;  
 60 begin  
 61   inherited;  
 62   EventTotal:= 0;  
 63   FreeOnTerminate:= True;  
 64   
 65   //初始化Winsock  
 66   WSAStartUp($202, WSData);  
 67   //创建套接字  
 68   ServerSocket:= Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);  
 69   //设置LocalAddr的参数  
 70   LocalAddr.sin_family:= AF_INET;   //IPV4族  
 71   LocalAddr.sin_addr.S_addr:= INADDR_ANY;//这里不能写Inet_addr('127.0.0.1'),否则会绑定失败,不清楚原因是什么;  
 72   LocalAddr.sin_port:= Htons(1077); //Host To Net Short,主机字节顺序转为网络字节顺序  
 73   //绑定本机IP地址、端口,绑定之前先设置好LocalAddr的参数  
 74   Bind(ServerSocket, PSOCKADDR(@LocalAddr), SizeOf(LocalAddr));  
 75   
 76   //创建EventObject  
 77   WSAEventObject:= WSACreateEvent();  
 78   //使用WSAEventSelect模型  
 79   WSAEventSelect(ServerSocket, WSAEventObject, FD_ACCEPT or FD_READ or FD_CONNECT);  
 80   //开始监听,最多同时监听5个连接  
 81   Listen(ServerSocket, 5);  
 82   
 83   SocketArray[EventTotal]:= ServerSocket;  
 84   WSAEventArray[EventTotal]:= WSAEventObject;  
 85   Inc(EventTotal);  
 86   
 87   while not Terminated do  
 88   begin  
 89     //用WSAWaitForMultipleEvents检测是否有“事件”发生  
 90     Idx:= WSAWaitForMultipleEvents(EventTotal, @WSAEventArray[0], False, WSA_INFINITE, False);  
 91     //判断发生了什么“事件”——读、写、断开等等  
 92     WSAEnumNetWorkEvents(SocketArray[Idx - WSA_WAIT_EVENT_0],  
 93       WSAEventArray[Idx - WSA_WAIT_EVENT_0], @WSANetEvents);  
 94   
 95     if (WSANetEvents.lNetworkEvents and FD_ACCEPT) > 0 then //如果是Accept事件  
 96     begin  
 97       ClientAddrLen:= SizeOf(ClientAddr);  
 98       ClientSocket:= Accept(SocketArray[Idx - WSA_WAIT_EVENT_0], ClientAddr, ClientAddrLen);  
 99   
100       WSAEventObject:= WSACreateEvent();  
101       WSAEventSelect(ClientSocket, WSAEventObject, FD_ACCEPT or FD_READ);  
102       SocketArray[EventTotal]:= ClientSocket;  
103       WSAEventArray[EventTotal]:= WSAEventObject;  
104       Inc(EventTotal);  
105     end;  
106   
107     if (WSANetEvents.lNetworkEvents and FD_READ) > 0 then //如果是Read事件  
108       if Recv(SocketArray[Idx - WSA_WAIT_EVENT_0], FBuff, SizeOf(FBuff), 0) > 0 then  
109         Synchronize(ShowRecv);  
110   end;  
111 end;  
112   
113 procedure TWorkThread.ShowRecv;  
114 begin  
115   FMemo.Lines.Add(FBuff);  
116 end;  
117   
118 procedure TForm1.FormCreate(Sender: TObject);  
119 begin  
120   TWorkThread.Create(Memo1);  
121 end;  
122   
123 end.  

1.WSAEventSelect需要Winsock2.0,可以google搜索Winsock2.pas
2.使用Bind的时候要注意:LocalAddr.sin_addr.S_addr:= INADDR_ANY;//这里不能写Inet_addr('127.0.0.1'),否则会绑定失败,不清楚原因是什么

本文转载自http://blog.csdn.net/dropme/article/details/4538553

posted on 2013-11-14 20:41  onlyou13  阅读(142)  评论(0编辑  收藏  举报