我需要在TCP连接关闭后才执行某些操作,也就是说 - 所有数据段,以及完成例程(FIN-ACK或RST)已执行并完成,以及 no packets will be sent on the wires .
由于 closesocket()
不是同步的,并且可以在完全关闭连接和套接字之前返回,因此我使用了 SO_LINGER
选项来获取关闭时刻 .
根据MSDN for closesocket中的说明,以及我的套接字是非阻塞(因而是异步)的事实,我编写了这段代码:
int ret;
/* config 2 secs of linger */
struct linger lng = {1, 2};
setsockopt(s, SOL_SOCKET, SO_LINGER, (const char*)&lng, sizeof(lng));
/* graceful close of TCP (FIN-ACK for both sides) */
shutdown(s, SD_BOTH);
/* linger routine for asynchronous sockets according to msdn */
do {
ret = closesocket(s);
} while (ret == SOCKET_ERROR && WSAGetLastError() == WSAEWOULDBLOCK);
/* my code to be run immediately after all the traffic */
printf("code to run after closing");
但是,closesocket调用返回零(成功;而不是进入循环),我在Wireshark中看到我的所有数据包都被发送之前调用了我的最终打印,所以 - 看起来像是无效的 .
顺便说一下,我用来打开和连接异步套接字的函数是 socket()
, WSAIoctl()
和它的 lpfnConnectEx()
回调 .
在完成TCP连接之前,lingered closesocket返回的原因是什么?有解决方案吗?