TCP三次握手及四次挥手

    从一个wireshark的抓包数据说起:

     三次握手:客户端向服务器发起请求时,会先通过三次握手建立连接,然后再进行数据传输。首先,客户端会向服务器发送一个SYN标识位为1的TCP报文,这里称为SYN包(ACK与FIN包同)。SYN包指明了客户端此时的序列号为0。服务端接收到报文后,会向客户端发送一个SYN+ACK包,指明服务端此时的序列号syn=0,以及作为客户端对应消息的回应返回了ack=0+1。客户端接收到消息,会向服务端发送一个ACK包,由于上一个SYN包消耗了一个序号,此时的序号为1,并且作为服务端序列号为0的消息的回应返回了ack=0+1。

    三次握手的流程如下:

     那么,为什么需要三次握手?

  • 初始化客户端及服务端的序列号
  • 保证信道的可靠

    TCB(TCP 传输控制块)是用于保存一个连接的所有信息的数据结构。如果在服务端发送SYN+ACK包后,未收到客户端返回的ACK包,那么服务器将以(1s 2s 4s 8s 16s 32s)的频率重发SYN+ACK包。如果仍未收到回复,则认为超时,连接无法建立,服务端释放对应资源。由于服务端会对上诉情况的连接持有一定时间,那么对应的TCB就将一直占用服务器存储。于是服务器维护了一个一定长度的backlog队列,用于控制TCB的存储上线。但这仍存在被syn flood攻击的风险。当恶意程序给服务端发送连接请求后,立即下线,由于服务端将对这个连接信息持有63s,恶意程序发送足够多的恶意请求后,backlog队列将被耗尽,导致服务端无法再接受新的连接请求。为了应对这种情况,当syn队列满了之后,服务器将通过tcp_syncookies回发syncookie参数,如果收到客户端的回应,则直接建立连接。

 

    四次挥手:服务端(或者客户端,在这个示例中是服务端先发起)在传输完数据后,在断开连接前,向客户端发送一个FIN+ACK包,序列号seq为m,作为回应的ack=n。客户端接收到消息后,回应对应的ACK包,seq=n,ack=m+1。TCP连接是一种全双工的连接,连接双发可同时进行数据的传输回应。此时,只是服务端通知了客户端己方的数据已传输完毕,而客户端可能还有数据需要进行传输。当客户端的数据也传输完成后,会再向服务端发送FIN+ACK包。由于示例中没有数据再进行传输,没有消耗序列号,客户端发送的序列号仍为n,作为回应的ack=m+1。服务端在收到消息后,回发ACK,seq=m+1,ack=n+1.回发后服务端并没有立即进入close状态,而是先等待2msl的时间,确保客户端有足够时间收到ACK包。如果客户端没有收到这个ACK,会再次发送FIN包。

    四次挥手的流程图如下:

     为什么需要四次挥手:

  • TCP是全双工的连接,需要确保客户端及服务端的数据都传输完毕才关闭连接

     当一方发起断开连接的消息后,另一方没有及时关闭连接,将可能导致服务器出现大量close_wait:

  •  应用程序代码没有正确释放连接
  •  线程配置不合理

  服务器会为每个用户保存一定的文件句柄数,当过多的close_wait导致被占用的通道达到上限时,新的请求将无法被处理。进一步产生too many open files异常,甚至服务器的奔溃。

     

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值