您的位置:首页 > 理论基础 > 计算机网络

TCP 第三次握手失败

2015-08-19 11:41 357 查看
这是另外一个问题,之前对于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重定向请求。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: