网络| TCP 三次握手

120 阅读2分钟

TCP是面向连接的协议,无论哪一方发送数据之前,都必须先在双方之间建立一条连接,在连接状态传输数据。

建立连接:三次握手

image.png

第一次

方向:客户端 -> 服务器

内容:标志SYN=1, ACK=0,序列号(ISN)= 客户端初始序列号m

描述:这个SYN段不携带任何数据,消耗一个序列号m。这一步客户端执行主动打开(Active Open)

第二次

方向:服务器 -> 客户端

内容:标志SYN=1, ACK=1;序列号= 服务器初始序列号 n;确认号= 客户端初始序列号m+1

描述:这个SYN/ACK段不携带数据,消耗一个序列号n。这一步服务器执行被动打开(Passive Open)。

第三次

方向:客户端 -> 服务器

内容:标志SYN=0, ACK=1;序列号= 客户端初始序列号m+1;确认号=服务器的初始序列号n+1

描述:这个ACK段不携带数据,不消耗序列号,

总结:经过上述3次握手后,TCP连接正式建立。双方都置ACK标志,交换并确认了对方的初始序列号,可以通过连接互相传输数据。

为什么是三次握手,而不是两次、四次、五次握手呢?

  1. 不是两次握手是因为,三次握手可以避免重复连接。

image.png

  • 客户端发送了序列号 m 请求时,由于没有收到服务端的回应,再次发起了 m+1 序列号的请求。此时期望收到服务端发送的确认号是 m+2。

  • 当客户端收到 服务端发送的确认号是 m+1 时,小于期望确认号,为过时的序列号,则拒绝该请求。

  • 服务端因为没有收到发出去的 初始序列号为 k 的响应,则关闭对应的连接,从而避免了重复连接。

  1. 可以设计成四次、五次握手,为了节省资源,三次握手就可以符合实际情况,所以就没必要设计成四次握手、五次握手。

为什么只能在客户端这边确认是否拒绝该请求?

服务端对所有的请求都进行响应,并确定那个请求是否已经过时。

由于并不知道客户端状态,服务器会不断发送SYN/ACK段,试图完成握手过程,这样会大量消耗服务器资源。如果人为利用这一点,就可以对服务器实施攻击,这就是所谓的SYN洪泛(SYN Flood)攻击。