TCP通信过程与三次握手和四次挥手

一、理论基础

TCP报文协议

TCP协议报文

  1. 源端口号:数据发起者的端口号,16bit

  2. 目的端口号:数据接收者的端口号,16bit

  3. 序号:32bit的序列号,由发送方使用

  4. 确认序号:32bit的确认号,是接收数据方期望收到发送方的下一个报文段的序号,因此确认序号应当是上次已成功收到数据字节序号加1。

  5. 首部长度:首部中32bit字的数目,可表示15*32bit=60字节的首部。一般首部长度为20字节。

  6. 保留:6bit, 均为0

  7. 紧急URG:当URG=1时,表示报文段中有紧急数据,应尽快传送。

  8. 确认比特ACK:ACK = 1时代表这是一个确认的TCP包,取值0则不是确认包。

  9. 推送比特PSH:当发送端PSH=1时,接收端尽快的交付给应用进程。

  10. 复位比特(RST):当RST=1时,表明TCP连接中出现严重差错,必须释放连接,再重新建立连接。

  11. 同步比特SYN:在建立连接是用来同步序号。SYN=1, ACK=0表示一个连接请求报文段。SYN=1,ACK=1表示同意建立连接。

  12. 终止比特FIN:FIN=1时,表明此报文段的发送端的数据已经发送完毕,并要求释放传输连接。

  13. 窗口:用来控制对方发送的数据量,通知发放已确定的发送窗口上限。

  14. 检验和:该字段检验的范围包括首部和数据这两部分。由发端计算和存储,并由收端进行验证。

  15. 紧急指针:紧急指针在URG=1时才有效,它指出本报文段中的紧急数据的字节数。

  16. 选项:长度可变,最长可达40字节

1、报文发送确认机制

简单理解就是,接收方需要对发送方进行回复确认,这是保证可靠传输的基础。

2、报文有序性机制

为了保证报文的有序性,那就必须对自己的报文按顺序进行编号,这样不但可以记录自己发送到了哪个包,接收方也可以根据序号对报文进行排序串接。

3、TCP对发送确认机制的利用

相对于UDP的不可靠,TCP是可靠的,要做到整个过程的可靠性,那么就需要对每个传输报文都进行发送确认,包括连接建立、数据交互、连接断开中,都可以拆分成无数个最基本的发送确认过程。

4、报文重传机制

TCP对有序性机制的利用,因为发送确认机制的存在,可以知道对方收到了第几个包,这就顺便可以知道哪些包是否需要重传。

5、报文初始序号生成机制

报文的初始序号是一个跟随时间而改变随机值,原因如下:

如果TCP在建立连接时每次都选择相同的、固定的初始序号,那么设想以下的情况:
(1)假定主机A和B频繁地建立连接,传送一些TCP报文段后,再释放连接,然后又不断地建立新的连接、传送报文段和释放连接。
(2)假定每一次建立连接时,主机A都选择相同的、固定的初始序号,例如,选择1。
(3)假定主机A发送出的某些TCP报文段在网络中会滞留较长的时间,以致造成主机A超时重传这些TCP报文段。
(4)假定有一些在网络中滞留时间较长的TCP报文段最后终于到达了主机B,但这时传送该报文段的那个连接早已释放了.而在到达主机B时的TCP连接是一条新的TCP连接。
这样,工作在新的TCP连接下的主机B就有可能会接受在旧的连接传送的、已经没有意义的、过时的TCP报文段(因为这个TCP报文段的序号有可能正好处在现在新的连接所使用的序号范围之中)。结果产生错误。
因此,必须使得迟到的TCP报文段的序号不处在新的连接中所使用的序号范围之中。
这样,TCP在建立新的连接时所选择的初始序号一定要和前面的一些连接所使用过的序号不一样。因此,不同的TCP连接不能使用相同的初始序号。

6、TCP报文初始序号互告

因为报文的初始序号是随机的,那就必须想办法让对方知道自己的序号是多少,TCP通信是依靠在双方建立连接的过程中交互了报文初始序号。

7、TCP报文的分类

请求连接报文:打开了同步标志位SYN=1的报文
回复确认报文:打开了确认标志ACK=1的报文
终止连接报文:打开了终止标志FIN=1的报文
数据传送报文:打开了数据推送标志位PST=1的报文

注意SYN、FIN、PST控制具体序号seq是同一个,而ACK控制的序号是ack。因为请求连接占用的序号位置是seq,回复确认占用的序号是ack,所以在三次握手的时候,服务端可以同时打开这两个标志位开关。

8、seq和ack序号递增规则

发送序号seq递增规则

只有收到了对方发来的标志位ACK=1的报文,并从收到的报文中提取ack值作为自己下次发送的seq,此时:自己seq = 对方ack;

确认序号ack的递增规则

  • 当收到了对方发来的标志位SYN=1的报文,此时报文长度len=0,自己的ack = 对方seq + 1;
  • 当收到了对方发来的标志位PSH=1的报文,此时报文长度len=n,自己的ack = 对方seq + n;
  • 当收到了对方发来的标志位FIN=1的报文,此时报文长度len=0,自己的ack = 对方seq + 1;
  • 当收到了对方发来只打开了ACK=1的报文,自己的ack值不变,因为这个报文只是纯确认报文,需要改变的是自己的seq值;

二、TCP通信完整过程

TCP通信完整图解
下面的描述是当认为所有报文都一次性成功的情况下进行,不涉及重传机制。

三、三次握手过程

三次连接报文
三次握手具体过程

  • 整个过程就是互相告知自己的初始序号,并得到对方确认的过程。

为什么不使用二次握手建立连接?

是因为服务端回复给客户端告知自己的初始序号后,得不到客户端的确认;

为什么不使用四次握手建立连接?

是因为第二次握手的时候,服务端回复确认客户端的同时,顺便告知了客户端,服务端自己的初始序号,这样就可以优化成三次握手。

1、 第1次握手,客户端发出SYN包

发送包:打开同步标志位SYN=1,自己的报文序号是seq=x,然后进入syn_sent状态;

2、第2次握手,服务端发出SYN和ACK包

1)先收包:服务端收到报文后知道了客户端的报文初始序号是x。因为收到SYN=1报文,根据递增规则,自身的ack=x+1,然后开始回复客户端:打开确认标志位ACK=1,
2) 回复包:我下次想要收到你的包的序号是ack=x+1;同时为了告知客户端知道自己的初始序号,该报文同时打开同步标志位SYN=1,服务端的初始序号seq=y,然后进入syn_rcvd状态;

3、第3次握手,客户端发出ACK包

1)先收包:收到服务端的报文,知道服务端的报文初始序号是y。
因为服务端报文是【SYN=1,seq=y】报文,所以自身的ack=y+1。
因为服务端的报文是【ACK=1,ack=x+1】,所以自身的seq=x+1。
2)回复包:回复给服务端ACK报文并把状态变成established,服务端收到该ACK后也变成established,此时的服务端因为收到客户端发来的【ACK=1,ack=y+1】,服务端的seq=y+1;

四、数据传输过程

数据传输报文

  • 根据报文可以看到,PSH包的Len字段会影响到接收端的Ack【接收端的Ack=发送端的Seq+发送端的Len】;
  • 整个报文可以看出,只有其中一端在不断发送数据(暂叫发送端),另外一端只是接收数据并回复ACK(暂叫接收端),所以接收的Seq没有递增,而发送端的Ack也没有递增;

五、四次挥手过程

断开连接报文
四次握手具体过程

整个过程其实可以拆分成两个二次挥手来理解

第1个二次挥手:客户端没有数据要发送了,通知服务端要断开连接,然后服务端回复确认收到了;
第2个二次挥手:服务端也没有数据要发送了,通知客户端要关闭连接,客户端回复服务端确认收到了。

为什么不使用二次挥手来断开连接?

因为当客户端要求服务端关闭后,服务端仍有数据发送,那么客户端肯定就要继续接收数据,如果使用二次握手,服务端发送完数据然后回复了客户端确认收到了报文然后就直接关闭了连接,这样的情况下,并不知道客户端是否接收完数据就把流给断了。同时,客户端在等服务端回复的时间可能过长。

为什么不使用三次挥手来断开连接?

因为客户端通知服务端要关闭,服务端有可能还未发送完数据,如果使用三次握手来关闭,此时服务端要一直等发送完毕所有数据,才能回复客户端收到了报文可以关闭连接了,可能会导致客户端等待时间过长。

1、第1次挥手:客户端发出FIN包

客户端没有数据要发送了,通知服务端要关闭连接,【终结标志位FIN=1,序号seq=u】,客户端进入FIN_WAIT1状态。
注意:此时的序号seq是根据前面客户端发了几个数据包决定的,这里当且认为是u。

2、第2次挥手:服务端发出ACK包

1)先收包:根据递增规则,服务端的ack=u+1
2)回复包:打开确认标志ACK=1,自身的seq=v;服务端进入CLOSE_WAIT状态,客户端进入FIN_WAIT2状态。
注意:此时的服务端序号seq是根据服务端在之前发了几个数据包决定的,这里当且认为当且的seq是v。

3、第3次挥手:服务端发出FIN包

服务端也没有数据要发送了,通知客户端要关闭连接。
因为在第二次握手后,可能继续发了N个包给客户端,所以此时的服务端seq变成了w。
因为在第二次握手后,没有再收到客户端的包了,可以知道此时服务端的ack仍然是ack=u+1;
服务端进入LAST_ACK状态。

4、第4次挥手:客户端发出ACK包

先收包:因为服务端的【ACK=1,ack=u+1】所以此时的客户端的seq=u+1;因为服务端的【FIN=1,seq=w】所以客户端的ack=w+1;
回复包:此时客户端方进入TIME_WAIT状态,经过2MSL时间后关闭连接;服务端收到ACK包后立即关闭。

参考文献

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值