TCP连接的三次握手与四次挥手
计算机网络课程估计有大半还给了老师,学习还是要时而复习才行,TCP连接作为计算机网络中重要的一部分内容,希望通过自己的复习与记录重新拾回来。
先记录几个关键字的意思:
- 同步 SYN :synchronous。建立连接,将 SYN = 1。
- 序号 seq: sequence。第一个字节的编号随机产生。
- 确认位 ACK : acknowledgement 。
- ack : 表示确认字段的值。
- 结束 FIN : finish。FIN = 1 表示希望断开连接。
1. 三次握手过程
- A 发送同步信号
SYN
和一个随机序列号seq = x
- B 确认收到 A 的同步信号,返回确认位
AKC = 1
,并将传来的x
加上 1 返回 - B 发送同步信号
SYN
和一个随机序列号seq = y
- A 确认收到 B 的同步信号,返回确认位
AKC = 1
,并将传来的 y 加上 1 返回,此时更新后的seq = x + 1
也一并返回
其中,2、3两步可以合并,也就是我们理解的三次握手,其实也可以这么理解,双方各发送一次请求,各进行一次确认,其中一次请求和确认合并在一起就是三次。
2. 四次挥手过程
- A 发送结束信号
FIN
给 B,和序列号seq = u
, u 等于 A 前面已传过的数据最后一个字节序号加1。 - B 确认收到 A 的结束信号,返回确认位
AKC = 1
、返回确认号ack= u + 1
,并返回序列号seq = v
,v 等于 B 前面已传过的数据最后一个字节序号加1。 - B 等待数据传送完毕,发送结束信号
FIN
给 A,和序列号seq = w
(假设等待期间又发送了一些数据),再次将确认位AKC = 1
、确认号ack= u + 1
一并返回。 - A 确认收到 B 的结束信号,返回确认位
AKC = 1
、返回确认号ack= w + 1
,将更新后的seq = u + 1
返回。
3.建立TCP连接为什么需要三次握手
找了网络上的各种三次握手文章,目前能了解的有下面这几种原因
1.1 防止旧的重复连接初始化造成混乱,避免资源浪费
谢希仁版《计算机网络》中的例子是这样的,“已失效的连接请求报文段” 的产生在这样一种情况下:client 发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达 server。本来这是一个早已失效的报文段。但 server 收到此失效的连接请求报文段后,就误认为是 client 再次发出的一个新的连接请求。于是就向 client 发出确认报文段,同意建立连接。假设不采用 “三次握手”,那么只要 server 发出确认,新的连接就建立了。由于现在 client 并没有发出建立连接的请求,因此不会理睬 server 的确认,也不会向 server 发送数据。但 server 却以为新的运输连接已经建立,并一直等待 client 发来数据。这样,server 的很多资源就白白浪费掉了。采用 “三次握手” 的办法可以防止上述现象发生。例如刚才那种情况,client 不会向 server 的确认发出确认。server 由于收不到确认,就知道 client 并没有要求建立连接。”
白话一点就是,如果只有两次握手,那么:
- A 向 B 发送了第一个请求,但是因为网络堵塞没有到达
- 超时后,于是 A 又发送了第二个请求,这此正常到达,而且 B 回复收到了
- A 这时就开始和 B 相互通信,并一段时间后结束了连接
- 此时最开始的请求到达了 B,B 以为 A 又请求了连接,并且回复了 A
- 但 A 认为自己并没有发送请求,所以并不会理睬 B, B 就只能一直等着
1.2 同步双方的初始序列号
举例:
- 例如客户端先发送了一个请求连接的数据包,初始
seq = 100
, 因为网络阻塞收不到回复,于是又发送了一个请求连接的数据包,初始seq = 200
- 此时网络又恢复了正常,服务端接收到了最开始发送的
seq = 100
, 于是返回ack = 101
- 客户端比较上下文,发现自己希望收到的
ack
应该是 201,于是发送了RST
给服务端,中止连接。 - 一段时间后
seq = 200
到达了服务端,并返回了ack = 201
以及自己的seq
- 客户端确认信息,返回服务端的
seq + 1
,建立TCP连接