我的客户端连发10条信息,在GetQueuedCompletionStatus之后先执行WSASendTo,那么这10条都能收到,如果把 WSASendTo注释掉,直接WSARecvFrom, 则只能收到第一条,而且每次我也将OVERLAPPED清空了,为什么呢?while(1)
{
bRet = GetQueuedCompletionStatus(pCServerDlg->g_hCompletionPort, // Completion Port
&BytesTransferred,(LPDWORD)&PerHandleData,(LPOVERLAPPED*)&PerIoData, INFINITE);if(BytesTransferred==0) //EOF
{
closesocket(PerHandleData->hClntSock);
free(PerHandleData);
free(PerIoData);
continue;
}if (bRet || &PerIoData->overlapped )
{
if (bRet)
{
PerIoData->wsaBuf.len=BytesTransferred;
//由于WSASendTo的注释掉引出问题
//WSASendTo(pCServerDlg->g_hSocket, &(PerIoData->wsaBuf), 1, NULL, 0,(SOCKADDR*) &P
//erHandleData->clntAddr, sizeof(PerHandleData->clntAddr),NULL, NULL);// RECEIVE AGAIN
memset(&(PerIoData->overlapped), 0, sizeof(OVERLAPPED));
PerIoData->wsaBuf.len=BUFSIZE;
PerIoData->wsaBuf.buf=PerIoData->buffer;flags=0;
int fromlen =sizeof(PerHandleData->clntAddr);
dwNumberOfBytesRecvd = 0;PerIoData->overlapped.hEvent = pCServerDlg->g_hReadEvent;
PerIoData->overlapped.Offset = 0;
PerIoData->overlapped.OffsetHigh = 0;int iRet = WSARecvFrom(pCServerDlg->g_hSocket,&(PerIoData->wsaBuf),1,&dwNumberOfBytesRecvd,
&flags,(SOCKADDR*) &PerHandleData->clntAddr, &fromlen,&(PerIoData->overlapped), NULL);if (!iRet )
{
DWORD dwErrCode = GetLastError();
if( dwErrCode != ERROR_IO_PENDING )
{
//
}
else if( dwErrCode == ERROR_IO_PENDING )
{
WaitForSingleObject(PerIoData->overlapped.hEvent,INFINITE);pCServerDlg->HandleIncomingData(PerHandleData, PerIoData);
}
}
else
{
pCServerDlg->HandleIncomingData(PerHandleData, PerIoData);
}continue;
}
else
{
fprintf (stdout, "WorkThread Wait Failed\n");
//exit (1);
}
}
{
bRet = GetQueuedCompletionStatus(pCServerDlg->g_hCompletionPort, // Completion Port
&BytesTransferred,(LPDWORD)&PerHandleData,(LPOVERLAPPED*)&PerIoData, INFINITE);if(BytesTransferred==0) //EOF
{
closesocket(PerHandleData->hClntSock);
free(PerHandleData);
free(PerIoData);
continue;
}if (bRet || &PerIoData->overlapped )
{
if (bRet)
{
PerIoData->wsaBuf.len=BytesTransferred;
//由于WSASendTo的注释掉引出问题
//WSASendTo(pCServerDlg->g_hSocket, &(PerIoData->wsaBuf), 1, NULL, 0,(SOCKADDR*) &P
//erHandleData->clntAddr, sizeof(PerHandleData->clntAddr),NULL, NULL);// RECEIVE AGAIN
memset(&(PerIoData->overlapped), 0, sizeof(OVERLAPPED));
PerIoData->wsaBuf.len=BUFSIZE;
PerIoData->wsaBuf.buf=PerIoData->buffer;flags=0;
int fromlen =sizeof(PerHandleData->clntAddr);
dwNumberOfBytesRecvd = 0;PerIoData->overlapped.hEvent = pCServerDlg->g_hReadEvent;
PerIoData->overlapped.Offset = 0;
PerIoData->overlapped.OffsetHigh = 0;int iRet = WSARecvFrom(pCServerDlg->g_hSocket,&(PerIoData->wsaBuf),1,&dwNumberOfBytesRecvd,
&flags,(SOCKADDR*) &PerHandleData->clntAddr, &fromlen,&(PerIoData->overlapped), NULL);if (!iRet )
{
DWORD dwErrCode = GetLastError();
if( dwErrCode != ERROR_IO_PENDING )
{
//
}
else if( dwErrCode == ERROR_IO_PENDING )
{
WaitForSingleObject(PerIoData->overlapped.hEvent,INFINITE);pCServerDlg->HandleIncomingData(PerHandleData, PerIoData);
}
}
else
{
pCServerDlg->HandleIncomingData(PerHandleData, PerIoData);
}continue;
}
else
{
fprintf (stdout, "WorkThread Wait Failed\n");
//exit (1);
}
}
while(1)
{
bRet = GetQueuedCompletionStatus(pCServerDlg->g_hCompletionPort, // Completion Port
&BytesTransferred,
(LPDWORD)&PerHandleData,
(LPOVERLAPPED*)&PerIoData, // OVERLAPPED
INFINITE
); if(BytesTransferred==0) //EOF
{
closesocket(PerHandleData->hClntSock);
free(PerHandleData);
free(PerIoData);
continue;
} PerIoData->wsaBuf.len=BytesTransferred;
WSASendTo(pCServerDlg->g_hSocket, &(PerIoData->wsaBuf), 1, NULL, 0,(SOCKADDR*) &PerHandleData->clntAddr,
sizeof(PerHandleData->clntAddr),NULL, NULL); // RECEIVE AGAIN
memset(&(PerIoData->overlapped), 0, sizeof(OVERLAPPED));
PerIoData->wsaBuf.len=BUFSIZE;
PerIoData->wsaBuf.buf=PerIoData->buffer; flags=0;
int fromlen =sizeof(PerHandleData->clntAddr); WSARecvFrom(pCServerDlg->g_hSocket,&(PerIoData->wsaBuf),1,NULL,
&flags,(SOCKADDR*) &PerHandleData->clntAddr, &fromlen,&(PerIoData->overlapped), NULL); pCServerDlg->HandleIncomingData(PerHandleData, PerIoData);
}问题同上。
PerIoData->overlapped.Offset = 0;
PerIoData->overlapped.OffsetHigh = 0;
////////////////////////////////////////////////////不要关联事件pCServerDlg->g_hReadEvent,否则WSARecvFrom(pCServerDlg->g_hSocket,&(PerIoData->wsaBuf),1,NULL,
&flags,(SOCKADDR*) &PerHandleData->clntAddr, &fromlen,&(PerIoData->overlapped), NULL);
将会触发事件,而不是完成端口
而且请注意我接收用的是刚开始定义的pCServerDlg->g_hSocket,而不是完成端口返回的PerHandleData->hClntSock,不过改过来也一样。这有什么区别吗?