ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

TCP三次握手,四次挥手异常情况(坑)

2021-11-01 16:03:08  阅读:169  来源: 互联网

标签:ACK 握手 SYN TCP server 四次 client FIN 连接


TCP三次握手,四次挥手异常情况(坑)

 

1、三次握手

 

(文中client,server均是相对而言)

 

  (1)、client第一个syn包丢失,没有收到server的ack,则client进行持续重传syn包。总尝试时间为75秒。参与文献《TCP/IP详解 卷1:协议》p178

  (2)、server收到了client的syn,并发出了syn+ack包,syn+ack包丢失。

    client方面,因为没收server的。将执行情况(1);

    server方面,超时时间内没有收到client的ack包(或者数据包),会持续发送syn+ack包;

  (3)、当Client端收到Server的SYN+ACK应答后,其状态变为ESTABLISHED,并发送ACK包给Server;

    如果此时ACK在网络中丢失,那么Server端该TCP连接的状态为SYN_RECV,并且依次等待3秒、6秒、12秒后重新发送SYN+ACK包,以便Client重新发送ACK包,以便Client重新发送ACK包。
  Server重发SYN+ACK包的次数,可以通过设置/proc/sys/net/ipv4/tcp_synack_retries修改,默认值为5。
  如果重发指定次数后,仍然未收到ACK应答,那么一段时间后,Server自动关闭这个连接。

  如果此时client向server发送数据包,server能正常接收数据。并认为连接已正常。参考:https://blog.csdn.net/zerooffdate/article/details/79359726

  应用层编写socket代码时,三次握手发生在client的connect,所以为了避免长时间(75秒)无响应连接,应设置为非阻塞socket,同时用select检测设置合适的超时时间。

 

2、四次挥手

      CLIENT                    SERVER

(1)、client发的FIN包丢了,对于client,因为没收对应的ACK包,应当一直重传(像普通包一样),直至到达上限次数,直接关闭连接;对于server,它应该无任何感知;

(2)、server回client的ACK包丢了,对于client,将执行(1),对于server将像丢普通的ack一样,再次收到FIN后,再发一个ACK包;

(3)、如果client收到ACK后,server直接跑路。client将永远停留在这个状态(半打开状态,就像client关闭了输出一样)。linux有tcp_fin_timeout这个参数,设置一个超时时间 cat /proc/sys/net/ipv4/tcp_fin_timeout 查看,默认60s,可否修改看linux具体版本; windows 注册表有TcpTimedWaitDelay,win10默认值30s;

(4)、server发的FIN包丢了,对于server,像丢普通的包一样,重传。若此时client早已跑路且与其他人建立的连接,client应会不认识这个FIN包,直接回个RST包给server。

如若client没跑路,且没收到server的FIN包,如(3)描述;

(5)、client回复ACK后,按道理来说,可以跑路了,但防止回复的ACK包丢失(丢失后,server因为没收FIN的ACK,所以会再发一个FIN),将等待2MSL(最大报文存活时间)(RFC793定义了MSL为2分钟,Linux设置成了30s)为什么要这有TIME_WAIT?为什么不直接给转成CLOSED状态呢?主要有两个原因:1)TIME_WAIT确保有足够的时间让对端收到了ACK,如果被动关闭的那方没有收到Ack,就会触发被动端重发Fin,一来一去正好2个MSL,2)有足够的时间让这个连接不会跟后面的连接混在一起(你要知道,有些自做主张的路由器会缓存IP数据包,如果连接被重用了,那么这些延迟收到的包就有可能会跟新连接混在一起),这期间如若再收到server的FIN,则再回复ACK;

 

题外话:

  可以看到时三次握手第二步时,server收到client的SYN包并回复SYN+ACK包后,server会把这条连接放入“半连接队列”。这边有个问题,假设这个client是恶意的,client只发SYN包,收到SYN+ACK后不回复,那在server方面,会一直存有这条“半连接”,client数量达到一定程序,serve就炸了。这就是所谓的SYN FLOOD攻击;那怎么防止这种情况呢?有下面几种方法:(来自RFC 4987

  1. 过滤
  2. 增加积压
  3. 减少SYN-RECEIVED定时
  4. 复用古老的半开通TCP
  5. SYN缓存
  6. SYN Cookie
  7. 混合方法
  8. 防火墙和代理

标签:ACK,握手,SYN,TCP,server,四次,client,FIN,连接
来源: https://www.cnblogs.com/djx123/p/15494131.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有