onlyou13

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
  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     FClientSocket: TSocket;  
 15     procedure ShowRecv;  
 16   protected  
 17     procedure Execute;override;  
 18   public  
 19     constructor Create(Memo: TMemo; ClientSocket: TSocket);  
 20   end;  
 21   
 22   TForm1 = class(TForm)  
 23     Memo1: TMemo;  
 24     Button1: TButton;  
 25     Timer1: TTimer;  
 26     procedure Timer1Timer(Sender: TObject);  
 27     procedure FormCreate(Sender: TObject);  
 28   private  
 29     { Private declarations }  
 30   public  
 31     { Public declarations }  
 32   end;  
 33   
 34 var  
 35   Form1: TForm1;  
 36   ServerSocket: TSocket;  
 37   
 38 implementation  
 39   
 40 {$R *.dfm}  
 41   
 42 { TWorkThread }  
 43   
 44 constructor TWorkThread.Create(Memo: TMemo; ClientSocket: TSocket);  
 45 begin  
 46   inherited Create(False);  
 47   
 48   FMemo:= Memo;  
 49   FClientSocket:= ClientSocket;  
 50 end;  
 51   
 52 procedure TWorkThread.Execute;  
 53 var  
 54   WSBuff: WSABuf;  
 55   EventTotal: Integer;  
 56   AcceptOverLapped: WSAOverLapped;  
 57   WSAEventArray: array [0..WSA_MAXIMUM_WAIT_EVENTS - 1] of WSAEvent;  
 58   
 59   Idx: Integer;  
 60   ReceiveBytes: DWORD;  
 61   Flags: DWORD;  
 62   ByteTransferred: DWORD;  
 63 begin  
 64   inherited;  
 65   FreeOnTerminate:= True;  
 66   EventTotal:= 0;  
 67   
 68   //创建事件  
 69   WSAEventArray[EventTotal]:= WSACreateEvent;  
 70   //置零  
 71   ZeroMemory(@AcceptOverLapped, SizeOf(WSAOverLapped));  
 72   //关联事件  
 73   AcceptOverLapped.hEvent:= WSAEventArray[EventTotal];  
 74   
 75   WSBuff.len:= 22;  //缓冲区的长度要大于客户端发送的长度,如果小于客户端发送长度,会出现乱码  
 76   WSBuff.buf:= FBuff;  
 77   Inc(EventTotal);  
 78   
 79   while not Terminated do  
 80   begin  
 81     //收消息  
 82     WSARecv(FClientSocket, @WSBuff, EventTotal, ReceiveBytes, Flags, @AcceptOverlapped, nil);  
 83     //用WSAWaitForMultipleEvents检测是否有“事件”发生  
 84     Idx:= WSAWaitForMultipleEvents(EventTotal, @WSAEventArray[0], False, WSA_INFINITE, False);  
 85     //用WSAGetOverlappedResult取得结果  
 86     WSAGetOverlappedResult(FClientSocket, @AcceptOverlapped, @ByteTransferred, False, Flags);  
 87     //显示收到的内容  
 88     Synchronize(ShowRecv);  
 89   
 90     //清零AcceptOverLapped  
 91     ZeroMemory(@AcceptOverLapped, SizeOf(WSAOverLapped));  
 92     //关联事件  
 93     AcceptOverLapped.hEvent:= WSAEventArray[Idx - WSA_WAIT_EVENT_0];  
 94   
 95     //重置Event  
 96     WSAResetEvent(WSAEventArray[Idx - WSA_WAIT_EVENT_0]);  
 97   end;  
 98 end;  
 99   
100 procedure TWorkThread.ShowRecv;  
101 begin  
102   FMemo.Lines.Add(FBuff);  
103 end;  
104   
105 procedure TForm1.FormCreate(Sender: TObject);  
106 var  
107   WSData: TWSAData;  
108   LocalAddr: TSockaddr;  
109   SocketMode: Cardinal;  
110 begin  
111   //初始化Winsock  
112   WSAStartUp($202, WSData);  
113   //创建套接字  
114   ServerSocket:= Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);  
115   //设置LocalAddr的参数  
116   LocalAddr.sin_family:= AF_INET;   //IPV4族  
117   LocalAddr.sin_addr.S_addr:= INADDR_ANY;//这里不能写Inet_addr('127.0.0.1'),负责会绑定失败,不清楚原因是什么;  
118   LocalAddr.sin_port:= Htons(1077); //Host To Net Short,主机字节顺序转为网络字节顺序  
119   //绑定本机IP地址、端口,绑定之前先设置好LocalAddr的参数  
120   Bind(ServerSocket, @LocalAddr, SizeOf(LocalAddr));  
121   
122   SocketMode:= 1;  
123   IoCtlSocket(ServerSocket, FIONBIO, SocketMode);  
124   
125   //开始监听  
126   Listen(ServerSocket, 5);  
127 end;  
128   
129 procedure TForm1.Timer1Timer(Sender: TObject);  
130 var  
131   ClientAddr: TSockAddr;  
132   ClientAddrLen: Integer;  
133   ClientSocket: TSocket;  
134 begin  
135   //接受客户端连接,为对应的客户端创建独立的线程  
136   ClientAddrLen:= SizeOf(ClientAddr);  
137   ClientSocket:= Accept(ServerSocket, ClientAddr, ClientAddrLen);  
138   if ClientSocket <> INVALID_SOCKET then  
139     TWorkThread.Create(Memo1, ClientSocket);  
140 end;  
141   
142 end. 



1.此代码只是为了学习函数的使用方法,为了使代码简单,此处使用Timer管理客户端连接,并为每个连接创建独立的线程,Overlapped的处理方式可在线程的执行部分查看,实际应用中不应该用这种模式
2.此代码为消息型的重叠(I/O Overlapped)模式,还有一种“完成例程”模式(非完成端口)

 

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

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