2012-11-07 93 views
0

凍結一旦我這是怎麼關閉套接字:關閉套接字()在一段時間

LINGER lingerStruct; 
lingerStruct.l_onoff = 1; 
lingerStruct.l_linger = 0; 
setsockopt(Clients[iClientID].ClientSocket, SOL_SOCKET, SO_LINGER, (char*)&lingerStruct, sizeof(lingerStruct)); 
CancelIo((HANDLE)Clients[iClientID].ClientSocket); 
shutdown(Clients[iClientID].ClientSocket, SD_BOTH); 
closesocket(Clients[iClientID].ClientSocket); // << Hangs here 

約2至10小時的運行時間和結賬超過500個插座後,它發生是隨機的插座不想要close和closesocket()永遠掛在關鍵部分(使用調試器發現這一點)。

我在做什麼錯了?

編譯:的Visual Studio 2010 SP1(C++) 操作系統:Windows Server 2008 R2 x64的

感謝。

+0

如果您知道它正在等待臨界區對象,那麼您可以使用windbg中的命令!locks來確定哪個線程擁有哪些臨界區對象。這很可能是死鎖。 – nanda

回答

1
LINGER lingerStruct; 
lingerStruct.l_onoff = 1; 
lingerStruct.l_linger = 0; 
setsockopt(Clients[iClientID].ClientSocket, SOL_SOCKET, SO_LINGER, (char*)&lingerStruct, sizeof(lingerStruct)); 

擺脫所有這一切。它對你沒有任何好處,或者是同伴。只需撥打closesocket(),讓TCP工作在默認模式。還是你故意試圖在同行中造成數據丟失和重置?如果是這樣,爲什麼?

CancelIo((HANDLE)Clients[iClientID].ClientSocket); 

我也會試圖擺脫這一點。關閉套接字應該照顧所有我會想到的,但我不是異步I/O的專家。你可以試試它。

shutdown(Clients[iClientID].ClientSocket, SD_BOTH); 

擺脫那。在closesocket()之前是多餘的。

1

CancelIo函數不是同步的,或者至少它沒有記錄爲保證同步。如果該套接字上的I/O處於掛起狀態,則應等待,直到收到完成通知,確認I/O已取消(或者可能在取消請求排隊之前成功完成)。

一旦收到完成通知,關閉套接字應該是安全的。