Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
确定TCP连接在C中真正关闭的时刻_C_Sockets_Winsock2_Closesocket_So Linger - Fatal编程技术网

确定TCP连接在C中真正关闭的时刻

确定TCP连接在C中真正关闭的时刻,c,sockets,winsock2,closesocket,so-linger,C,Sockets,Winsock2,Closesocket,So Linger,只有在TCP连接完全关闭后,我才需要执行一些操作,也就是说,所有数据段以及完成例程(FIN-ACK或RST)都已执行,并且不会在线路上发送数据包 由于closesocket()不是同步的,可能会在连接和套接字完全关闭之前返回,因此我使用了SO\u LINGER选项来获取关闭的时刻 根据MSDN中关于closesocket的说明,以及我的套接字是非阻塞的(因此是异步的),我编写了以下代码: int ret; /* config 2 secs of linger */ struct linger

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

由于
closesocket()
不是同步的,可能会在连接和套接字完全关闭之前返回,因此我使用了
SO\u 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中看到,在发送所有数据包之前调用了我的最终打印,因此-看起来玲珑器不起作用

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


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

。老实说,也许您应该让远程端响应ACK以确认收到数据,然后在收到数据后关闭并继续。除了最终的解决方案只提供给Linux之外,我还尝试在closesocket()之前添加一个等待的send()和recv(),但这并没有解决问题。一旦您完成对套接字的写入,您必须通过shutdown(shuth_WR)发送FIN,然后通过read()等待剩余的数据/FIN-ACK/RST,直到它返回。如果您在不读取的情况下关闭套接字,直到它返回,正如我所说的,我试图等待recv(),但在打印后会发送对FIN-ACK的最终确认。