Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/23.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
Linux 同时TCP终止和后续连接():EADDRNOTAVAIL_Linux_Sockets_Networking_Tcp - Fatal编程技术网

Linux 同时TCP终止和后续连接():EADDRNOTAVAIL

Linux 同时TCP终止和后续连接():EADDRNOTAVAIL,linux,sockets,networking,tcp,Linux,Sockets,Networking,Tcp,我的公司为特殊目的发布了一个特殊的TCP堆栈,我的任务是实现符合RFC793的关闭序列。其中一个单元测试有一个服务器在特殊的TCP堆栈上工作,与一个普通的LinuxTCP客户机通信,我遇到了一些奇怪的行为,我不确定这是由我的编程错误引起的还是预期的 在我的工作开始之前,我们通常在用户应用程序调用close时发送RST数据包。我已经实现了FIN握手,但我注意到,在两端同时进行TCP终止FIN_WAIT_1->CLOSING->TIME_WAIT的情况下,如图所示,标准Linux TCP客户端无法再

我的公司为特殊目的发布了一个特殊的TCP堆栈,我的任务是实现符合RFC793的关闭序列。其中一个单元测试有一个服务器在特殊的TCP堆栈上工作,与一个普通的LinuxTCP客户机通信,我遇到了一些奇怪的行为,我不确定这是由我的编程错误引起的还是预期的

在我的工作开始之前,我们通常在用户应用程序调用close时发送RST数据包。我已经实现了FIN握手,但我注意到,在两端同时进行TCP终止FIN_WAIT_1->CLOSING->TIME_WAIT的情况下,如图所示,标准Linux TCP客户端无法再次连接到相同的目标地址和端口,而connect返回EADDRNOTAVAIL,直到TIME_WAIT进入CLOSED之后

现在,标准Linux客户端应用程序设置选项SO_REUSEADDR,每次将套接字绑定到端口8888,并连接到目标端口6666。我的问题是,为什么绑定成功,为什么连接失败?我本以为REUSEADDR可以接管一个本地时间等待端口,它确实做到了,但是connect有什么不利于再次与目标ip:6666通信呢

我的代码是否做了不应该做的事情,或者这是预期的行为

我可以确认,对于失败的连接,没有任何SYN数据包使其脱离客户机。我已经附上了上述课程的FIN握手截图


您以前的实现使用RST结束连接。收到RST数据包后,立即从活动连接表中删除连接。这是因为在该连接上不存在进一步接收有效数据包的可能性:对等方刚刚告诉您的系统该会话无效

另一方面,如果您使用FIN进行适当的会话终止,则会出现最后一个数据包问题:您如何确定对等方是否确实收到了您发送给其FIN的最后一次确认?这是TCP的TIME_WAIT状态的定义?如果对方没有收到,他们可能会有效地发送另一份FIN数据包副本,然后您的机器应该重新确认

现在,您的绑定成功了,因为您正在使用SO_REUSEADDR,但是您仍然无法创建两侧端口完全相同的新连接,因为该条目仍处于活动连接表的TIME_WAIT状态。4元组IP1、端口1、IP2、端口2必须始终是唯一的


正如@EJP在评论中所建议的,客户端指定端口是不寻常的,通常没有理由这样做。我想更改您的测试。

“标准Linux客户端应用程序设置了此选项,以便每次都将套接字绑定到8888端口。”为什么?你关心本地出站端口是什么吗?@EJP我没有编写单元测试,我想确保我的更改没有破坏任何东西。软件的主线版本发送一个重置,你看,所以当第二次测试到来时,端口已经关闭,所以这不会发生。我很好奇我所观察到的是否是预期的。从你的经验中,有什么东西能给你带来这样或那样的启示吗?谢谢你的回答,这很让人放心。你知道为什么只有在两端都在等待的时候才会发生上述错误吗?我可以确认这只发生在同时终止时,当双方都去时间等待,而不是在任何其他情况下。在Linux中选择这种设计的原因是什么。。。我希望每次主动关闭时都会发生这种情况,也就是说,发送第一个FIN的一侧,或者同时关闭的两侧。您的软件是否可能没有正确处理等待时间?也就是说,从技术上讲,如果客户端IP上的端口8888已经有一对处于TIME\u WAIT状态的端口的连接条目,那么它不应该接受从端口6666到该端口的新连接请求,但是如果您还是这样做了,并且简单地重写了该条目,则很少会导致可见的问题。此外,正如您所看到的,当客户端处于TIME\u WAIT状态时,您的SYN数据包永远不会离开机箱,因此无论服务器端的状态如何都无关紧要。最后,这种行为是TCP规范的一部分,因此不是真正的linux设计选择。我运行了相同的客户端和服务器应用程序,这次都是在linux的标准TCP/IP堆栈上运行的。我可以确认客户机何时执行活动关闭。目前,我在服务器代码中的关闭函数之前添加了一个sleep,并验证了tcpdump捕获,但没有发生此错误。