1. 同時發送多個WSARecv消息處理,多餘的會有什麼情況?
使用代碼測試,顯示結果爲全部返回錯誤997,表示都可以正常發出recv操作,且多個工作線程同時在檢測此socket的多個recv消息,運行片刻立即關閉Client端,發現工作線程出現的異常,1個或2個工作線程中的closesocket函數調用失敗,錯誤碼爲10038,因此要盡力避免對同一個socket向完成端口發送重複的同一信息。在接受數據時並沒有出現重複現象(內部有同步),也就是說只有在斷開socket時會有很小不出錯的可能,跟線程調度有關。
測試代碼如下:Server端:
(偵聽線程)
......
//成功與Client建立連接
while(1)
{
while(WSARecv(Accept, &(PerIoData->DataBuf), 1, &RecvBytes, &Flags,
&(PerIoData->Overlapped), NULL) ==SOCKET_ERROR && WSAGetLastError() ==ERROR_IO_PENDING)
{
printf("WSARecv()2 failed with error %d/n", WSAGetLastError());
Sleep(1000);
}
printf("WSARecv() succeed!/n");
Sleep(5000);
}
......
(工作線程)
......
while(TRUE)
{
//完成端口有消息來了
if (GetQueuedCompletionStatus(CompletionPort, &BytesTransferred,
(LPDWORD)&PerHandleData, (LPOVERLAPPED *) &PerIoData, INFINITE) == 0)//PerIoData的其他數據成員由此函數在收到數據時填充
{
if(GetLastError() ==64)//套接字無效,有人掉線了
{
printf("Invalid socket %d was closed!/n", PerHandleData->Socket);
if(closesocket(PerHandleData->Socket) ==SOCKET_ERROR)
{
printf("closesocket() failed with error %d/n", WSAGetLastError());
return 0;
}
GlobalFree(PerHandleData);
GlobalFree(PerIoData);
printf("PerIoData at %d was freed!/n", PerIoData);
continue;
}
}
printf("GetQueuedCompletionStatus() 返回BytesTransferred ==%d/n", BytesTransferred);//------
printf("PerIoData->DataBuf.buf ==%s/n", PerIoData->DataBuf.buf);
printf("completion routine running---------/n");
}
Client端:
......
//connect成功與Server取得鏈接
while(1)
{
//獲取鍵盤輸入,並保存
cin>>lpPerIoData->Buffer;
lpPerIoData->DataBuf.buf =lpPerIoData->Buffer;
lpPerIoData->DataBuf.len =DATA_BUFSIZE;
//發送數據
if(WSASend(Client, &(lpPerIoData->DataBuf), 1, &(lpPerIoData->BytesSEND),
0, &(lpPerIoData->Overlapped), NULL) ==SOCKET_ERROR)
{
printf("WSASend() failed with error %d/n", WSAGetLastError());
Sleep(1000);
return;
}
else
printf("Send Succeed!/n");
Sleep(5000);
}
Server打印信息見圖片。
2.同時發送多個WSASend消息處理
由於是異步操作所以這個消息經常是立即成功返回0的,但是當完成端口內部的服務線程(不是指工作線程)有很多消息要處理的時候應該會返回997錯誤,因此WSASend消息是有可能被堆積在未完成消息隊列裏的,如果服務線程同時執行鍼對同一個socket的send操作"可能"(這裏是我猜的)會引起數據的混亂,因此不應重複調用WSASend發送消息。
3.同時發送WSARecv和WSASend消息
這兩者不衝突。