TCP中的三次握手与四次挥手

数据报

TCP三次握手

TCP四次挥手

为什么连接的时候是三次握手,关闭的时候却是四次握手?

为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?


数据报

首先要谈TCP中的三次握手四次挥手我们必须知道TCP中的数据报

其中一行有32位,也就是4个字节。

第一行,源端口号目的端口号各占16位,这两者代表发送端与接受端的地址。

第二行,是序号(seq)有32位。

第三行,是确认序号(ack)有32位,注意要和下面的ACK区分开来。

第四行,比较重要的就是6个标志位,不过常用的就3个。

  • ACK:确认标志位,只有1位,即只能表示1(有效)和0(无效)。
  • SYN:代表发起一个新的连接,只有1位。

当SYN=1而ACK=0时,表明这是一个连接请求报文。对方若同意建立连接,则应在响应报文中使SYN=1和ACK=1。因此,SYN置1就表示这是一个连接请求或连接接受报文。

  • FIN:代表结束一个连接,只有1位。

TCP三次握手

我上网搜了两张图片,应该大致能说明这个问题。

TCP怎样才能保证可靠的传输任务,就是通过三次握手,也可以说三次握手是TCP建立连接时使用的方案。如下图所示:

注:seq应该位32位!但是为了方便画图所以用10000代替。

x

(1)首先由Client发出请求连接SYN=1,确认标志位ACK=0,序号seq=10000(假设)

(2)然后 Server 进行回复确认,即 SYN=1,seq=20000,确认标志位ACK=1,确认序号ack=10001(10000 + 1),此时服务端接收数据没有问题,但是客户端接收数据不知道会不会出问题!

(3)最后 Client 再进行一次确认,但不用请求连接SYN 了,这时即为确认标志位ACK=1,序号seq=10001(表示Client发出的第二条信息,所以seq递增加一),确认序号ack=20001,此时客户端接受服务端的数据没有问题。

TCP四次挥手

四次挥手是指TCP要断开连接时做的事情

(1)由Client发起关闭连接的请求,即FIN=1,seq=25368(以上述的10000,每发送一条就+1,一直加到了25368)

(2)Server端收到了关闭请求,所以要做出应答确认标志位ACK=1确认序号ack=25369

(3)Server端将要发送的数据发完之后,就最后回复一条FIN=1,序号位10568。

(4)客户端收到后回复一个ACK=1,表示收到了,ack=10569,服务器端关闭,2MSL后客户端关闭。

简单的来说就是:

(1)假设Client端发起中断连接请求,也就是发送FIN报文。Server端接到FIN报文后,意思是说"我Client端没有数据要发给你了",但是如果你(服务器端)还有数据没有发送完成,则不必急着关闭Socket,可以继续发送数据。

(2)所以你(服务器端)先发送ACK,"告诉Client端,你的请求我收到了,但是我还没准备好,请继续你等我的消息"。这个时候Client端就进入FIN_WAIT状态,继续等待Server端的FIN报文

(3)当Server端确定数据已发送完成,则向Client端发送FIN报文,"告诉Client端,好了,我这边数据发完了,准备好关闭连接了"。

(4)Client端收到FIN报文后,就知道可以关闭连接了,但是他还是不相信网络,怕Server端不知道要关闭,所以发送ACK后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。Server端收到ACK后,"就知道可以断开连接了"。

Client端等待了2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,我Client端也可以关闭连接了。Ok,TCP连接就这样关闭了!(是服务端先关闭,后客户端关闭)

为什么连接的时候是三次握手,关闭的时候却是四次握手?

因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。

但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"

只有等到Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假设网络是不可靠的,有可能最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文

posted @   金鳞踏雨  阅读(25)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
历史上的今天:
2021-04-12 班级考勤管理系统
点击右上角即可分享
微信分享提示