为什么三次握手?
TCP 协议的双方通信(客户端/服务端), 为了实现可靠数据传输,有序性,都必须维护一个序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到的。 三次握手的过程即是通信双方相互告知序列号起始值, 并确认对方已经收到了序列号起始值的必经步骤
如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认,序号没有同步,数据就会乱序
防止服务器端因接收了早已失效的连接请求报文,从而一直等待客户端请求,最终导致> 形成死锁、浪费资源 (这种情况下面没有解释,我在这里简单解释一下,客户端发起第一次握手,服务端收到后,会开辟一个链接端口,然后给客户端,此时如果网络不好,发生超时,客户端没有收到,防止服务器端因接收了早已失效的连接请求报文,从而一直等待客户端请求,最终导致形成死锁、浪费资源)
TCP 通信流程介绍
三次握手详解
解释为什么需要三次握手? 能不能不握手?
这里就引出了 TCP 与 UDP 的一个基本区别, TCP 是可靠通信协议, 而 UDP 是不可靠通信协议。(UDP没有握手这个流程)
- TCP 的可靠性含义: 接收方收到的数据是完整, 有序, 无差错的。
- UDP 不可靠性含义: 接收方接收到的数据可能存在部分丢失, 顺序也不一定能保证。
UDP 和 TCP 协议都是基于同样的互联网基础设施, 且都基于 IP 协议实现, 互联网基础设施中对于数据包的发送过程是会发生丢包现象的
为什么 TCP 就可以实现可靠传输, 而 UDP 不行?
TCP 协议为了实现可靠传输, 通信双方需要判断自己已经发送的数据包是否都被接收
方收到, 如果没收到, 就需要重发。 为了实现这个需求, 很自然地就会引出序号(sequence number) 和确认号(acknowledgement number) 的使用。
发送方在发送数据包(假设大小为 10 byte)时, 同时送上一个序号( 假设为 500),那么接收方收到这个数据包以后,就可以回复一个确认号(510 = 500 + 10) 告诉发送方 “我已经收到了你的数据包, 你可以发送下一个数据包, 序号从 510开始” 。
为什么需要三次握手,而非两次
正如上文所描述的,为了实现可靠传输,发送方和接收方始终需要同步( SYNchronize )序号。 需要注意的是, 序号并不是从 0 开始的, 而是由发送方随机选择的初始序列号 ( Initial Sequence Number, ISN )开始 。 由于 TCP是一个双向通信协议, 通信双方都有能力发送信息, 并接收响应。 因此, 通信双方都需要随机产生一个初始的序列号, 并且把这个起始值告诉对方。
1、我们接通吧,我从456开始给我的信息编号
2、知道了!我准备好接收457号信息了。另外,我会从123开始给邮件编号
3、好的!我准备接收124号信息
四次挥手过程:
特别说明:为什么TCP释放连接需四次挥手?
结论 :即释放连接后,都无法接收 / 发送消息给对方
具体描述:
延伸疑问:为什么客户端关闭连接前要等待2MSL时间?
- 即 TIME - WAIT 状态的作用是什么;
- MSL = 最长报文段寿命(Maximum Segment Lifetime)
原因1:为了保证客户端发送的最后1个连接释放确认报文 能到达服务器,从而使得服务器能正常释放连接 (客户端的第四次挥手可能丢失,如果立马关闭连接,服务器收不到客户端的最后一个释放报文会重发,此时客户端已经关闭了,会导致服务端连接关闭不了。
所以客户端要等到2倍报文存活时间,确保服务端关闭)
原因2:防止 上文提到的早已失效的连接请求报文 出现在本连接中。
客户端发送了最后1个连接释放请求确认报文后,再经过2MSL时间,则可使本连接持续时间内所产生的所有报文段都从网络中消失。
即 在下1个新的连接中就不会出现早已失效的连接请求报文