TCP三次握手和四次挥手详解

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

文章目录

三次握手和四次挥手简述

三次握手即客户端与服务端进行的三次通信。四次挥手就是客户端和服务端通过四次通信释放连接也叫连接终止协议。

三次握手的目的

三次握手是为了让客户端和服务端分别确认自己和对方接收和发送消息的能力是正常的。

三次握手流程详解

三次握手

序号报文路径客户端状态报文信息服务器状态目的
第一次握手C->SSYN_SENTSYN=1,seq=xLISTENC自己发信息正常
S自己收信息正常C发消息正常
第二次握手S->CSYN_SENTSYN=1,ACK=1,
seq=y,ack=x+1
SYN_RCVDC:自己收信息正常S收发信息正常
S: 自己发消息正常但S不知道C收消息是否正常->需要第三次握手
第三次握手C->SESTABLISHEDACK=1,seq=x+1,ack=y+1ESTABLISHEDS:C接收信息正常
  1. 初始时客户端处于Closed状态服务器处于Listen状态
  2. 第一次握手客户端发送SYN报文给服务器初始序列号为xseq=x, 此时客户端进入SYN_SENT状态这时客户端可以知道自己发送能力正常服务器可以知道自己接收能力正常客户端发送能力正常。
  3. 第二次握手服务器通过自己的SYN报文给与客户端确认和响应服务器进入SYN_RECV状态这时客户端可以知道服务器收发能力正常自己收发能力正常服务器知道自己收发能力正常但不知道客户端接收能力正常因此需要第三次握手。服务器发送报文的四个参数具体含义如下
    1. SYN=1表示为连接请求报文也不能携带数据
    2. seq=y服务端的序列号为y
    3. ACK=1表示确认客户端序列号有效此时确认号ack有值
    4. ack=seq+1ack的值为客户端传来的序列号seq加1即ack=x+1
  4. 第三次握手客户端收到服务器的SYN+ACK的包此时客户端处于ESTABLISHED(已确认)状态表示客户端和服务器都表示同意连接因此客户端发送一个ACK报文ack仍为序列号+1即y+1,初始序列号为x因此客户端发送的第二次报文序列号要+1即x+1;这时服务器可以确认客户端收发能力正常第三次握手可以携带数据
  • SYN=1或ACK=1表明这是一个连接请求报文
  • SYN=1时的报文不能携带数据如果可以携带数据的话如果有人在第一次握手的SYN报文放入很多数据重复发送大量的这些报文服务器就会消耗大量内存缓存这些报文服务器就更容易被攻击。

半连接队列和全连接队列

完成第一次和第二次握手后的TCP连接讲socket放到半连接队列中

完成第三次握手后socket会从半连接队列移到全连接队列当调用accpet函数时从全连接队列中返回可用的socket给用户进程。

四次挥手的目的

TCP是全双工的工作模式因此每个方向都必须单独进行关闭。当一方完成自己的数据发送任务后就可以发送一个FIN报文来终止这个方向的连接。

全双工客户端在给服务器端发送消息的同时服务器端也可以给客户端发送消息
半双工客户端可以给服务端发消息服务器端也可以给客户端发消息但客户端和服务端不能同时发。

四次挥手详解

四次挥手

  1. 刚开始客户端和服务器端都处于ESTABLISHED状态假如客户端发起关闭请求
  2. 第一次挥手客户端向服务器发送FIN报文FIN=1,seq=u发完后进入FIN_WAIT_1状态即主动关闭TCP连接不再发送数据但可以接收服务器发来的报文等待服务器回复
  3. 第二次挥手服务器接到FIN报文后返回一个ACK报文ACK=1,ack=u+1,seq=v表明自己接收到此报文服务器进入CLOSE_WAIT关闭等待状态此时客户端就知道服务端接到自己的断开连接请求进入到FIN_WAIT_2状态TCP处于半关闭状态但服务器端可能还有数据要传输。
  4. 第三次挥手服务器关闭客户端连接发送FIN报文FIN=1seq=w,ack=u+1给客户端此时服务器处于LAST_ACK状态等待客户端回应。
  5. 第四次挥手客户端收到FIN报文后发送一个ACKACK=1,ack=w+1,seq=u+1给服务器作为应答此时客户端处于TIME_WAIT状态这个状态是为了等待足够的时间以确保TCP接收到连接中断请求的确认
  6. 注意这时服务器到客户端的TCP连接并未被释放客户端需要经过等待2MSLMSL表示一个报文的来回时间后才会进入CLOSED状态这样做的目的是确保服务器收到自己的ACK报文如果在规定时间没有收到客户端发的ACK那么服务器会重发FIN客户端再次收到FIN报文就知道自己的ACK丢了然后会重发ACK给服务器。服务器收到ACK后就会关闭连接处于CLOSE状态了。
  7. 等待2MSL的原因
  • 防⽌客户端最后⼀次发给服务器的确认在⽹络中丢失以⾄于客户端关闭⽽服务端并未关闭导致资源的浪费。
  • 等待最⼤的2msl可以让本次连接的所有的⽹络包在链路上消失以防造成不必要的⼲扰。

如果客户端直接closed然后⼜向服务端发起了⼀个新连接我们不能保证这个新连接和刚关闭的连接的端⼝号是不同的。假设新连接和已经关闭的⽼端⼝号是⼀样的如果前⼀次滞留的某些数据仍然在⽹络中这些延迟数据会在新连接建⽴后到达服务端所以socket就认为那个延迟的数据是属于新连接的数据包就会发⽣混淆。所以客户端要在TIME_WAIT状态等待2倍的MSL这样保证本次连接的所有数据都从⽹络中消失。

序号报文路径客户端状态报文信息服务器状态
第一次挥手C->SFIN_WAIT_1FIN=1,seq=uESTABLISHED
第二次挥手S->CFIN_WAIT_2ACK=1,seq=v,ack=u+1CLOSE_WAIT
第三次挥手S->CFIN_WAIT_2FIN=1,seq=v,ack=u+1LAST_ACK
第四次挥手C->STIME_WAITACK=1,ack=w+1,seq=u+1CLOSED

为什么客户端需要TIME_WAIT状态

假设最终的ACK丢失服务器会重发FIN客户端必须维护TCP状态信息以便可以重发最终的ACK否则就发送RSTTCP连接出错结果服务端认为发生错误。TCP实现必须可靠地终止连接的两个方向全双工关闭客户端必须进入TIME_WAIT状态以免可能出现重发ACK的情形

为什么挥手比握手多一次

因为握手的时候并没有数据传输所以服务端的** SYN 和 ACK 报文可以一起发送**但是挥手的时候有数据在传输所以 ACK 和 FIN报文不能同时发送需要分两步所以会比握手多一步。

为什么三次挥手不行

因为服务端在接收到FIN, 往往不会立即返回FIN 必须等到服务端所有的报文都发送完毕了才能发FIN。因此先发一个ACK表示已经收到客户端的FIN延迟一段时间才发FIN。这就造成了四次挥手。

如果是三次挥手会造成
如果将服务端的两次挥手合为一次等于说服务端将ACK和FIN的发送合并为一次挥手这个时候长时间的延迟可能会导致客户端误以为FIN没有到达客户端从而让客户端不断的重发FIN。所有只能第二次握手先发送ACK确认接收到了客户端的数据等服务器发送完了数据再发送FIN包进行第三次挥手。

TCP报文参数释义

在三次握手和四次挥手中报文发送都会携带一些参数这些参数的具体解释如下

  • SYN同步序列号标志位,tcp三次握⼿中第⼀次会将SYN=1,ACK=0此时表⽰这是⼀个连接请求报⽂段对⽅会将SYN=1,ACK=1表⽰同意连接连接完成之后将SYN=0

  • FIN在tcp四次挥⼿时第⼀次将FIN=1表⽰此报⽂段的发送⽅数据已经发送完毕这是⼀个释放链接的标志

  • ACK当ACK=1时我们的确认序列号ack才有效当ACK=0时确认序号ack⽆效,TCP规定所有建⽴连接的ACK必须全部置为1

  • 序号(seq):占 32位4 个字节序号范围[02^32-1]序号增加到 2^32-1 后下个序号又回到 0。TCP 是面向字节流的通过 TCP 传送的字节流中的每个字节都按顺序编号而报头中的序号字段值则指的是本报文段数据的第一个字节的序号。例如:我们的seq = 201携带的数据有100那么最后⼀个字节的序号就为300那么下⼀个报⽂段就应该从301开始.

  • 确认号(ack):占 32位4 个字节期望收到对方下个报文段的第一个数据字节的序号。当标志位ACK值为1时才能产生有效的确认号ack。并且:ack=seq+1;

  • RST当RST=1时表明TCP连接出现严重错误此时必须释放连接之后重新连接,⼜叫重置位.

  • URG紧急指针标志位当URG=1时表明紧急指针字段有效.它告诉系统中有紧急数据应当尽快传送这时不会按照原来的排队序列来传送.⽽会将紧急数据插⼊到本报⽂段数据的最前⾯

  • PSH推送操作,提示接收端应用程序立即从TCP缓冲区把数据读走

ACK、SYN和FIN这些大写的单词表示标志位其值要么是1要么是0ack、seq小写的单词表示序号

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6