【TCP】从开撩到分手:3次握手与4次挥手

目录

0.TCP数据段结构

0.1 TCP首部

1.三次握手

2.四次挥手

3. 常见问题

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

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

3.3 为什么不能用两次握手进行连接?

3.4 如果已经建立了连接,但是客户端突然出现故障了怎么办?


0.TCP数据段结构

一个TCP段包含TCP首部header和TCP数据部分data,首部以32位,4字节一行如下所示:

0.1 TCP首部

源端口目的端口TCPsocket端口,发送端端口,接收方端口
序号 seq4B,报文段中的第一个字节的数据编号,下次发送则是lastSeq+lastLen
确认号 ack4B,对端下个字节的序号
offset标识位窗口数据偏移表示是整个数据的字节下标便于拼接,标识位标识那种类型
校验和紧急指针校验和校验数据完整性;
options填充 

 

标识位:占1位

字段含义
URG紧急指针是否有效。为1,表示某一位需要被优先处理
ACK

确认号是否有效,一般置为1。

1时,有效。ACK=0无效

PSH提示接收端应用程序立即从TCP缓冲区把数据读走。
RST对方要求重新建立连接,复位。
SYN

请求建立连接,同步序号(序列号的字段设定)。建立连接,设置为1

FIN

希望断开连接。发起方数据已经发送完毕,并要求释放连接

终止FIN: 用来释放一个连接。

1.三次握手

3次握手:客户端SYN,服务端ACK-SYN,客户端ACK

客户端状态:CLOSED->SYN-SENT->ESTABLISHED

服务端状态:LISTEN->SYN-RCVD->ESTABLISHED

2.四次挥手

断开连接,可以由客户端发起,也可以由服务断发起,当服务端主动断开连接时,一般客户端继续发送报文会收到Connection reset的异常信息。

四次挥手的由四次特殊的包传输:主动FIN 被动ACK;被动FIN,主动ACK

发起断连的一方(active 主动方)的4个状态流转如下图左边所示:ESTABLISHED->FIN_WAIT1->FIN_WAIT2->TIME_WAIT

被动断开的一方(passive 被动方)的4个状态流转如右边所示:ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSE

3. 常见问题

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

答:因为Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。

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

答:虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是网络是不可靠的,最后一个ACK有可能丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。在Client发送出最后的ACK回复,但该ACK可能丢失。Server如果没有收到ACK,将不断重复发送FIN,Client不能立即关闭,须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。

3.3 为什么不能用两次握手进行连接?

答:3次握手完成两个重要的功能,既要双方做好发送数据的准备工作(双方都知道彼此已准备好),也要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认。

现在把三次握手改成仅需要两次握手,死锁是可能发生的。作为例子,考虑计算机S和C之间的通信,假定C给S发送一个连接请求分组,S收到了这个分组,并发 送了确认应答分组。按照两次握手的协定,S认为连接已经成功地建立了,可以开始发送数据分组。可是,C在S的应答分组在传输中被丢失的情况下,将不知道S 是否已准备好,不知道S建立什么样的序列号,C甚至怀疑S是否收到自己的连接请求分组。在这种情况下,C认为连接还未建立成功,将忽略S发来的任何数据分 组,只等待连接确认应答分组。而S在发出的分组超时后,重复发送同样的分组。这样就形成了死锁。

3.4 如果已经建立了连接,但是客户端突然出现故障了怎么办?

答:TCP还设有一个保活计时器,显然,客户端如果出现故障,服务器不能一直等下去,白白浪费资源。服务器每收到一次客户端的请求后都会重新复位这个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75分钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值