TCP 第三次握手失败

这是另外一个问题,之前对于TCP握手以及通信底层没有什么概念。出现问题后,客户发来了Wireshark抓包。


客户端101.253发出了SYN包给服务器102.24, 客户端进入SYN_SEND状态。    

服务器收到SYN包后发出SYN+ACK数据包,服务器进入SYN_RECV状态。  

客户端收到SYN+ACK后发出ACK给服务器,客户端进入ESTABLISH状态

服务器收到最后的ACK,                                   服务器进入ESTABLISH状态。


从上面可以看出,当客户端收到SYN+ACK后,然后发出ACK给服务器,客户端就认为连接上了服务器。 一般情况下,服务器会收到客户端的ACK,服务器认为自己连接上了客户端。  不过,也有可能服务器并没有收到ACK。

这时候,客户端认为自己连上了服务器,而服务器认为自己并没有连上客户端。客户端的动作,接下来可能会直接发送数据给服务器,就像上图中的PSH+ACK。

服务器可能会收到PSH+ACK,也可能没有收到。但不管如何,服务器此时的状态还是SYN_RECV。服务器不会进行任何动作,除了催促客户端”我还需要一个ACK"。因此,3秒钟后,服务器会重新发送SYN+ACK给客户端。若6秒后还没有得到ACK,服务器会再次发送....

上面的客户端发送了PSH+ACK,有可能会得到服务器的回应ACK+SYN,也有可能没有(比较ACK+SYN需要3秒的超时时间)。 不管如何,客户端希望服务器回复的是指定序号的ACK。客户端也会设定一个超时定时器,它会再次发送PSH+ACK来提醒服务器“我需要你的ACK来确认你是否收到数据”


现在问题清楚了,由于第三次握手失败,导致服务器的状态不对。客户端虽然认为自己已经建立了连接,但是数据发送不到服务器。 可是为什么会这样?

我找到了这个连接http://jasonccie.blog.51cto.com/2143955/391024

客户的网络结构和链接提到的只是有点不一样:


对于服务器来说,它的路由ICMP的重定向包修改。因此,每次发往客户端的数据包都不会经过路由器。而客户端发给服务器的数据包每次都会经过路由器。

路由器上的防火墙再转发第3次握手的SYN包时,检查到服务器并没有将第2次握手SYN+ACK包,认为客户端的第3次握手的SYN是无效的,从而并没有转发这个数据包。导致服务器收不到第3次握手无法建立连接。


解决办法是路由器禁止掉ICMP重定向,或者服务器忽略掉路由器的ICMP重定向请求。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值