我用的是TCP协议,服务端创建listen socket.
m_socListener = WSASocket(
AF_INET,
SOCK_STREAM,
0,
NULL,
0,
WSA_FLAG_OVERLAPPED
);我把客户端连接的socket 关联到完成端口之后,另外开启一个线程等待客户端的数据,
while(1)
{
BOOL bIORet = GetQueuedCompletionStatus(
m_hCompletionPort,
&dwIoSize,
(LPDWORD) &lpClientContext,
&lpOverlapped,
INFINITE);
if (!bIORet)
{
clear_err_socket(lpClientContext);
}}可是再客户端发送数据之后,GetQueuedCompletionStatus()函数没有唤醒,
或者说GetQueuedCompletionStatus()函数没有任何反映,
就是客户端再关闭时候调用
shutdown(clientSocket);
也不会收到任何消息。
请指教。可以肯定的是我已经关联到完成端口了,而且客户端显示发送数据成功。
也就是数据已经到达服务器了,
m_socListener = WSASocket(
AF_INET,
SOCK_STREAM,
0,
NULL,
0,
WSA_FLAG_OVERLAPPED
);我把客户端连接的socket 关联到完成端口之后,另外开启一个线程等待客户端的数据,
while(1)
{
BOOL bIORet = GetQueuedCompletionStatus(
m_hCompletionPort,
&dwIoSize,
(LPDWORD) &lpClientContext,
&lpOverlapped,
INFINITE);
if (!bIORet)
{
clear_err_socket(lpClientContext);
}}可是再客户端发送数据之后,GetQueuedCompletionStatus()函数没有唤醒,
或者说GetQueuedCompletionStatus()函数没有任何反映,
就是客户端再关闭时候调用
shutdown(clientSocket);
也不会收到任何消息。
请指教。可以肯定的是我已经关联到完成端口了,而且客户端显示发送数据成功。
也就是数据已经到达服务器了,
等 Receive 到数据后 GetQueuedCompletionStatus() 就唤醒了。
{
SOCKET sock; ... while(true)
{
sock = accept(...); ... PostQueuedCompletionStatus(...);
} return 0;
}DWORD CALLBACK ThreadPoolProc(LPVOID pvArg)
{
BOOL bRet;
... while(true)
{
bRet = GetQueuedCompletionStatus(...); ... WSARecv(...) ...
} return 0;
}
等 Receive 到数据后 GetQueuedCompletionStatus() 就唤醒了。已经激活了
而且能正常处理手工 POST 的消息。
但是就是不响应网络的消息,。
郁闷。
而后completion要和thread中的 GetQueuedCompletionStatus确定了吗?
ULONG ulFlags = MSG_PARTIAL;UINT nRetVal = WSARecv(
m_Socket,
&m_wsaInBuffer,
1,
&dwIoSize,
&ulFlags,
&pOverlap->m_ol,
NULL);if ( nRetVal == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING)
{
// error.
return false;
}
以下的我 认为时问题的关键,望各位帮忙看看时怎么回事。在accept 完成之后
手工 GetQueuedCompletionStatus()的消息。
完成端口可以正常接受到消息,
可是就是不响应网络的消息,。
郁闷。
DWORD WINAPI
AcceptThread(LPVOID lParam)
{
while(1)
{
socClient = WSAAccept(
m_socListener,
NULL,
NULL, NULL, 0);
if ( socClient==INVALID_SOCKET )
{
break;
}
if ( CreateIoCompletionPort(
(HANDLE)socClient,
m_hCompletionPort,
(DWORD)pContext,
0) != m_hCompletionPort )
{
break;
} ClientContextPtr pContext = new ClientContext();
pContext->socClient;
m_pContextList->Add(pContext);
OVERLAPPEDPLUS *pOverlap = new OVERLAPPEDPLUS(IOInitialize);
//这个消息GetQueuedCompletionStatus()正常接受到了。
//而且我观察GetQueuedCompletionStatus()调用得到的 pContext结构没有任何问题。
BOOL bSuccess = PostQueuedCompletionStatus
(
m_hCompletionPort,
0,
(DWORD) pContext,
&pOverlap->m_ol
);
if ( (!bSuccess && GetLastError() != ERROR_IO_PENDING) )
{
m_pContextList->Remove(pContext);
}
}
}可要是客户端发送的网络消息GetQueuedCompletionStatus()
函数没有任何反应,
甚至客户端调用shutdown(clientSocket )也一样。
m_socListener = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
改为
m_socListener = socket(AF_INET, SOCK_STREAM, 0);
在while循环里加上 ::WSAREcv();
来触发完成端口