closesocket()暂时冻结一次

时间:2012-11-07 03:43:20

标签: windows sockets hang

这就是我关闭套接字的方式:

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个套接字后,碰巧这个随机套接字不想关闭,closesocket()会永久挂在一个关键部分(使用调试器发现这个)。

我做错了什么?

编译器:Visual Studio 2010 SP1(C ++) 操作系统:Windows Server 2008 R2 x64

感谢。

2 个答案:

答案 0 :(得分: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 :(得分:1)

CancelIo函数不是同步的,或者至少没有记录为保证同步。如果该套接字上的I / O处于挂起状态,您应该等到收到完成通知,确认I / O已取消(或者,可能在取消请求排队之前成功完成)。

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