呵呵,我现在先不管初始化,和其它处理方式,我不太理解的地方是在
GetQueuedCompletionStatus处理方式,我现在来说说Server中的Client在WorkThread中的工作思路
在Server.Accept一个ClientSocket时,建立一个TServerClientSocket实例,并将这个实例
关联到CompletionPort中,那WorkerThread::GetQueuedCompletionStatus取出来的就是
TServerClientSocket这个实例,那么这个实例在WorkerThread线程进行工作
ClientSocket.WorkBlock(Block, Transfered);
而不是PPerHandleData,因为CompletionKey即是DWORD,传一个PPerHandleData指针,还不如
俺去传一个对象,俺就可以懒一点了。
WorkBlock最大的处理就是维护一次Client交互中数据的处理,它的数据应该在WSABUF中,而其它
PPerHandleData应该是Client在Server中的附加信息,应该是在Client中进行相应变化。
Transfered的数量是一次I/O完成的数量,如果为0的话,那么Client是出错了,也就是说,
客户机可能超时,可能断开,那么就应该Free这个Client了。
一个包如果大于WSABUF中的MaxCount,那应该就是维护这个Client.WorkBlock中的处理,
所以我觉得应该对每个Client中应该有OnDataIn, OnDataOut这个函数,进行回调出在主
界面(主线程)中需要发送/读出的数据,那么再进行投递。完成一个交互。
function WorkerThread(AServer: TServerSocket): DWORD; stdcall;
var
Block: PBlock;
Transfered: DWORD;
ClientSocket: TServerClientSocket;
begin
Result := 0;
while True do
begin
ClientSocket := nil;
if not GetQueuedCompletionStatus(AServer.CompletionPort, Transfered,
DWORD(ClientSocket), POverlapped(Block), INFINITE) then
begin //调用失败
if Assigned(ClientSocket) then
FreeAndNil(ClientSocket);
Continue;
end;
if Cardinal(Block) = SHUTDOWN_FLAG then //Server断开Client
break;
if Transfered = 0 then //I/O读写返回0,可能超时,可能断开连接。
begin
FreeAndNil(ClientSocket);
Continue;
end;
case ClientSocket.WorkBlock(Block, Transfered) of
RESPONSE_UNKNOWN:
FreeAndNil(ClientSocket);
RESPONSE_FAIL:
break;
end;
end;
end;