//
// 这个函数解释清楚了整个机制也就明白了...
// 首先我们看CompletionPort应该没有问题,是从创建线程的主线程传过来的.
// BytesTransferred指明了这次IO传输了多少Bytes...
// PerHandleData是CreateIoCompletionPort的时候穿过来的,MSDN里面叫CompletionKey.
// 请注意PerIoData这个参数,本来按照MSDN的解释如下:
// "Pointer to a variable that receives the address of the OVERLAPPED structure that was
// specified when the completed I/O operation was started."
// 其实在这这个lpOverlapped传过来的就是上面WSARecv传入的overlapped的地址...
// 这下明白了吧:主线程借着overlapped的名声传了一个结构体指针过来..:-)
//
if (GetQueuedCompletionStatus(CompletionPort, &BytesTransferred,
(LPDWORD)&PerHandleData, (LPOVERLAPPED *) &PerIoData, INFINITE) == 0)
{
printf("GetQueuedCompletionStatus failed with error %d\n", GetLastError());
return 0;
}
//
// First check to see if an error has occured on the socket and if so
// then close the socket and cleanup the SOCKET_INFORMATION structure
// associated with the socket.
//
if (BytesTransferred == 0)
{
printf("Closing socket %d\n", PerHandleData->Socket);
if (closesocket(PerHandleData->Socket) == SOCKET_ERROR)
{
printf("closesocket() failed with error %d\n", WSAGetLastError());
return 0;
}
//
// Check to see if the BytesRECV field equals zero. If this is so, then
// this means a WSARecv call just completed so update the BytesRECV field
// with the BytesTransferred value from the completed WSARecv() call.
//
if (PerIoData->BytesRECV > PerIoData->BytesSEND)
{
//
// Post another WSASend() request.
// Since WSASend() is not gauranteed to send all of the bytes requested,
// continue posting WSASend() calls until all received bytes are sent.
//
ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED));
1.Socket Modes",什么是"Socket I/O Models"?
Socket Modes : Determines how winsock functions behave when called with a socket.
Socket I/O Models : Describes how an application manages and processes I/O on a socket.
这种方式的一个缺点是:应用程序很难同时通过多个建立好连接的socket通信.当然话说回来我们可以为每一个连接好的socket都开一个Reading Thread and WorkThread,但是呢这会带来很大的开销,而且扩展性很差,试想:如果用这样的模型建立一个服务器端来一个连接开至少两个线程...天..要是业务负担很大/连接的socket很多的话怎么办??所以说别多想了...
这样的方式是很不适合做服务器端的.(注意:我说的服务器端是指C/S中的S端逻辑).
DXServerCore
Ancestor to all of the DXSock™ Protocol implementations - consisting of the "VCL" component, the listener thread, and client or session thread definitions. DXServerCore and all descendants inherit our high-performance socket layer (DXSock), along with the 4 different threading models contained in the DXServerCore listener thread. As a new connection is detected, the listener thread spawns a new client thread - properly configuring the socket layer object, and fires the OnNewConnect event with the associated client thread as the property. This design allows the listener thread to process millions of connections a second, and off-loads latency to each individual client thread; which is approximately 0.001ms per new session.