加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

linux – 为什么套接字连接被阻止,TCP内核保留重传[ACK]数据包

发布时间:2020-12-13 22:50:23 所属栏目:Linux 来源:网络整理
导读:我们面临的问题是,从一段时间后,特定的套接字连接被阻止,客户端的tcp内核不断重传[ACK]数据包. 拓扑流程如下: Client A ←→ Switch A ← Router A:NAT ← .. Internet .. → Router B:NAT → Switch B ←→ Server B 以下是WireShark捕获的数据包: A)服务
我们面临的问题是,从一段时间后,特定的套接字连接被阻止,客户端的tcp内核不断重传[ACK]数据包.

拓扑流程如下:

Client A ←→ Switch A ← Router A:NAT ← .. Internet .. 
               → Router B:NAT → Switch B ←→ Server B

以下是WireShark捕获的数据包:
A)服务器

1. 8013 > 6757 [PSH,ACK] Seq=56 Ack=132 Win=5840 Len=55     
2. 6757 > 8013 [ACK] Seq=132 Ack=111 Win=65425 Len=0

B)客户

//lines 3 and 4 are exactly the same as line 1 and 2      
3. 8013 > 13000 [PSH,ACK] Seq=56 Ack=132 Win=5840 Len=55      
4. 13000 > 8013 [ACK] Seq=132 Ack=111 Win=65425 Len=0     
5. 13000 > 8013 [PSH,ACK] Seq=132 Ack=111 Win=65425 Len=17     

[TCP Retransmission]          
6. 13000 > 8013 [PSH,ACK] Seq=132 Ack=111 Win=65425 Len=17

8013是服务器端口,6757是客户端NAT端口.

为什么TCP内核继续传输[ACK]数据包
告诉客户端它收到数据包1(见数据包4,5和6),甚至
当服务器已经收到一个[ACK]数据包时(参见数据包2)?
当问题发生时,连接的任何一侧都不会关闭套接字.

在数据包6之后,连接丢失,我们无法发送任何内容
服务器再通过该套接字.

psuedocode:  
         //client
         serverAddr.port =htons(8013) ;
         serverAddr.ip = inet_addr(publicIPB);
         connect(fdA,serverAddr,...);         

         //server
         listenfd = socket(,SO_STREAM,);
         localAddr.port = htons(8013);
         localAddr.ip = inet_addr(INADDR_ANY);
         bind(localAddr...)
         listen(listenfd,100);

         ...
         //using select model
         select(fdSet,NULL,NULL);
         for(...)
         {
         if (FD_ISSET(listenfd))
            {
            ...
              }
         ...
         }

UPDATE
UP1.以下是重现问题的具体步骤

>鉴于三台计算机是PC1,PC2和PC3.
???????当Server落后时,这三个都落后于RouterA
???????RouterB的.
>给定两个用户,分别是U1和U2.
???????U1从PC1登录,U2从PC3登录.都
???????U1和U2将在它们之间建立一个tcp连接
???????和服务器.现在U1能够通过它发送数据
???????tcp连接到Server,然后Server中继所有数据
???????到U2.到目前为止,一切正常.

表示与Server对应的套接字号
???????U1和Server之间TCP连接的端点:
???????U1-OldSocketFd
>请勿注销U1,并拔下PC1的电缆.
???????然后U1从PC2登录,现在它建立一个新的
???????TCP连接到服务器.

表示与Server对应的套接字号
???????U1和Server之间TCP连接的端点:
???????U1-NewSocketFd

从服务器端,它更新其会话时
???????使用U1,它调用close(U1-OldSocketFd).

4.1.在步骤3之后大约30秒,我们发现了U1 IS
?????????????无法通过新的TCP向服务器发送任何数据
?????????????连接.

4.2.在步骤3中,如果服务器不调用close(U1-OldSocketFd)
?????????????立即(U1之间的第二个新连接相同
?????????????而服务器已建立),而不是服务器调用
?????????????然后关闭(U1-OldSocketFd)超过70-80秒
?????????????一切正常.

UP2.路由器B在端口8013上使用端口转发.
UP3.服务器运行的Linux OS的一些参数.

net.ipv4.tcp_tw_reuse = 1
    net.ipv4.tcp_tw_recycle = 1

解决方法

数据包1(相同于3)和2(相同于4)经过后,您的客户端似乎正在向服务器传输17个字节的数据(数据包5).我不知道在第一次交换数据包之后数据包5有多少,所以我不知道这发生了多少时间.您的伪代码不会澄清它,因为它只显示套接字初始化,它没有显示哪一方尝试在什么时间传输什么数据.在此实例中,ladder diagram可能有助于表示协议交换.

在任何情况下,服务器显然不会确认17字节的数据,因此它们会再次传输(数据包6).

除非您在网络或防火墙或NAT路由器或其他丢弃数据包时出现问题,否则服务器无法接收TCP交换机的早期部分,但显然无法接收数据包5或6再次,在先前的数据交换和数据包5之间是否经过了大量的时间(例如,NAT路由器,防火墙或负载均衡器有足够的时间使连接失效)?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读