2012-11-07 92 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已取消(或者可能在取消请求排队之前成功完成)。

一旦收到完成通知,关闭套接字应该是安全的。