2

我只需要在 TCP 连接完全关闭后执行一些操作,也就是说 - 所有数据段以及完成例程(FIN-ACK 或 RST)都已执行并完成,并且不会有任何数据包在电线上发送

由于closesocket()不是同步的并且可以在连接和套接字完全关闭之前返回,我使用该SO_LINGER选项来获取关闭的时刻。

根据 MSDN 中关于 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 中看到我的最终打印是在所有数据包发送之前调用的,所以 - 看起来 linger 不起作用。

顺便说一句,我用来打开和连接异步套接字的函数是socket()WSAIoctl()以及它的lpfnConnectEx()回调。

在 TCP 连接完全完成之前,徘徊的 closesocket 返回的原因是什么?有解决办法吗?

4

0 回答 0