TCP的三次握手四次挥手

1、TCP(Transfer control protocol)传输控制协议

(1)两种传输模式:
TCPUDP
面向有连接面向无连接
可靠高速
常用于点对点常用于点对面
如:微信通话如:直播
(2)数据方向:

在互联网的通信中,永远是客户端主动连接到服务端

(3)字段简介:

序列号seq:占4个字节,用来标记数据段的顺序,TCP把连接中发送的所有数据字节都编上一个序号,第一个字节的编号由本地随机产生;给字节编上序号后,就给每一个报文段指派一个序号;序列号seq就是这个报文段中的第一个字节的数据编号。

确认号ack:占4个字节,期待收到对方下一个报文段的第一个数据字节的序号;序列号表示报文段携带数据的第一个字节的编号;而确认号指的是期望接收到下一个字节的编号;因此当前报文段最后一个字节的编号+1即为确认号。

确认ACK:占1位,仅当ACK=1时,确认号字段才有效。ACK=0时,确认号无效。

同步SYN:连接建立时用于同步序号。当SYN=1ACK=0时表示:这是一个连接请求报文段。若同意连接,则在响应报文段中使得SYN=1ACK=1。因此,SYN=1表示这是一个连接请求,或连接接受报文。SYN这个标志位只有在TCP建产连接时才会被置1,握手完成后SYN标志位被置0

终止FIN:用来释放一个连接。FIN=1表示:此报文段的发送方的数据已经发送完毕,并要求释放运输连接。

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

(4)三次握手:

在这里插入图片描述

第一次握手(连接请求):客户端发送syn(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;

第二次握手(确认请求):服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

第三次握手(连接确认):客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。

握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP连接都将被一直保持下去。断开连接时服务器和客户端均可以主动发起断开TCP连接的请求,断开过程需要经过“四次挥手”。

字段含义
URG紧急指针是否有效
若为1则表示某一位需要被优先处理
ACK确认号是否有效,一般置为1
PSH提示接收端应用程序立即从TCP缓冲区把数据读走
RST对方要求重新建立连接,复位
SYN请求建立连接,并在其序列号的字段进行序列号的初始值设定
建立连接,设置为1
FIN希望断开连接
客户端 服务器 客户端主动打开 ---------------- 服务器被动打开 LISTEN 收听 我 可 以 连 接 到 你 吗 ?( 连 接 请 求 ) SYN-SENT 同步已发送 当 然 可 以( 确 认 请 求 ) SYN-RCVD 同步已收到 那 就 开 始 吧( 连 接 确 认 ) ESTAB-LISHED 已建立连接 ESTAB-LISHED 已建立连接 客户端 服务器
状态理解
LISTEN监听
SYN-SENTSYN已发送
SYN-RCVDSYN已接收
ESTAB-LISHED已连接
(5)四次挥手:

在这里插入图片描述
第一次挥手客户端发送一个 FIN,用来关闭客户端服务器的数据传送,客户端进入 FIN_WAIT_1 状态。

第二次挥手服务器收到 FIN 后,发送一个 ACK客户端,确认序号为收到序号 +1(与 SYN 相同,一个 FIN 占用一个序号),服务器进入 CLOSE_WAIT 状态。

第三次挥手服务器发送一个 FIN,用来关闭服务器客户端的数据传送,服务器进入 LAST_ACK 状态。

第四次挥手客户端收到 FIN 后,客户端进入 TIME_WAIT 状态,接着发送一个 ACK服务器,确认序号为收到序号 +1服务器进入 CLOSED 状态,完成四次挥手。

如果有大量的连接,每次在连接、关闭时都要三次握手,四次挥手,会很明显会造成性能低下,因此,HTTP 有一种叫做 keep connection 的机制,它可以在传输数据后仍然保持连接,当客户端再次获取数据时,直接使用刚刚空闲下的连接而无需再次握手:
在这里插入图片描述

客户端 服务器 客户端主动关闭 ------------------------------------------ 服务器被动关闭 ESTAB-LISHED ESTAB-LISHED 我 要 跟 你 断 开 连 接( 断 开 请 求 ) FIN_WAIT_1 收 到 了,但 我 要 先 处 理 其 它 客 户 端 连 接( 收 到 请 求 ) CLOSE_WAIT FIN_WAIT_2 我 准 备 好 跟 你 断 开 连 接 了( 确 认 请 求 ) LAST_ACK 那 就 断 开 吧( 断 开 确 认 ) TIME_WAIT CLOSED CLOSED 客户端 服务器

2、常见面试题:

【问题1】 为什么要进行第三次握手?

为了防止服务器端开启一些无用的连接增加服务器开销以及防止已失效的连接请求报文段突然又传送到了服务器端,因而产生错误。由于网络传输是有延时的(要通过网络光纤和各种中间代理服务器),在传输的过程中,比如客户端发起了 SYN=1 创建连接的请求(第一次握手),如果服务器端就直接创建了这个连接并返回包含 SYN、ACKSeq 等内容的数据包给客户端,这个数据包因为网络传输的原因丢失了,丢失之后客户端就一直没有接收到服务器端返回的数据包。客户端可能设置了一个超时时间,时间到了就关闭了连接创建的请求。再重新发出创建连接的请求,而服务器端是不知道的,如果没有第三次握手告诉服务器端客户端收的到服务器端传输的数据的话,服务器端是不知道客户端有没有接收到服务器端返回的信息的。

还有一种情况是已经失效的客户端发出的请求信息,由于某种原因传输到了服务器端服务器端以为是客户端发出的有效请求,接收后产生错误。所以我们需要“第三次握手”来确认这个过程,让客户端服务器端能够及时地察觉到因为网络等一些问题导致的连接创建失败,这样服务器端的端口就可以关闭了不用一直等待。也可以这样理解:“第三次握手”是客户端服务器端发送数据,这个数据就是要告诉服务器端客户端有没有收到服务器端“第二次握手”时传过去的数据。若发送的这个数据是“收到了”的信息,接收后服务器端就正常建立TCP连接,否则建立TCP连接失败,服务器端关闭连接端口。由此减少服务器端开销和接收到失效请求发生的错误。

【问题2】 为什么连接的时候是三次握手,关闭的时候却是四次握手?

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

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

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

【问题4】 为什么不能用两次握手进行连接?

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

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

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

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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

~莘莘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值