1

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

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

谢谢。

4

2 回答 2

1

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

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

于 2012-11-07T09:16:13.000 回答
0
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()

于 2012-11-07T06:05:28.753 回答