5.8.1 TCP的运输连接管理——TCP的连接建立.pdf

概念

image.png

这三个阶段就是我们听说最久的:
三次挥手建立连接、建立连接后进行数据传输、四次挥手释放TCP连接

  • TCP的运输连接管理就是使用运输连接的建立和释放都能正常的进行

    TCP的连接建立

  • TCP 建立连接的过程叫做握手

  • 握手需要在客户和服务器之间交换三个 TCP 报文段。称之为三报文握手
  • 采用三报文握手主要是为了防止已失效的连接请求报文段突然又传送到了,因而产生错误。

    TCP的连接建立要解决以下三个问题

    image.png

    TCP使用“三报文握手”建立连接

  • TCP 连接的建立采用客户服务器方式

  • 主动发起连接建立的应用进程叫做TCP客户 (client)。
  • 被动等待连接建立的应用进程叫做TCP服务器 (server)。

“握手”需要在TCP客户端和服务器之间交换三个TCP报文段
过程
image.png

在三报文握手过程中,有两个角色客户端发送握手连接请求,服务器等待接收请求。

在最开始:双方都是处于关闭状态,此时双方的TCP进程都是关闭的。

此时,服务器在连接之前要进行准备
image.png

一开始,TCP服务器进程首先创建传输控制块,用来存储TCP连接中的一些重要信息。例如TCP连接表、指向发送和接收缓存的指针、指向重传队列的指针,当前的发送和接收序号等 之后,就准备接受TCP客户端进程的连接请求 此时,TCP服务器进程就进入监听状态,等待TCP客户端进程的连接请求

值得注意的是:
TCP服务器进程是被动等待来自TCP客户进程的连接请求。而不是主动发起,因此称为被动打开连接。
与服务器类似,客户端进程也需要进行准备:
image.png

TCP客户进程也是首先创建传输控制块

由于TCP连接建立是由TCP客户端主动发起的,因此称为主动打开连接
准备完毕后开始”握手“:
第一次发送握手报文:
image.png

然后,在打算建立TCP连接时,向TCP服务器进程发送TCP连接请求报文段,并进入同步已发送状态 TCP连接请求报文段首部中

  • 同步位SYN被设置为1,表明这是一个TCP连接请求报文段
  • 序号字段seq被设置了一个初始值x,作为TCP客户端进程所选择的初始序号

请注意:TCP规定SYN被设置为1的报文段不能携带数据,但要消耗掉一个序号

服务器收到信号后,发送第二次握手报文:
image.png

TCP服务器进程收到TCP连接请求报文段后,如果同意建立连接,则向TCP客户进程发送TCP连接请求确认报文段,并进入同步已接收状态 TCP连接请求确认报文段首部中

  • 同步位SYN和确认位ACK都设置为1,表明这是一个TCP连接请求确认报文段
  • 序号字段seq被设置了一个初始值y,作为TCP服务器进程所选择的初始序号
  • 确认号字段ack的值被设置成了x+1,这是对TCP客户进程所选择的初始序号(seq)的确认

请注意:这个报文段也不能携带数据,因为它是SYN被设置为1的报文段,但同样要消耗掉一个序号

发送方接收到确认报文后,开始第三次握手:
image.png

TCP客户进程收到TCP连接请求确认报文段后,还要向TCP服务器进程发送一个普通的TCP确认报文段,并进入连接已连接状态 普通的TCP确认报文段首部中

  • 确认位ACK被设置为1,表明这是一个普通的TCP确认报文段
  • 序号字段seq被设置为x+1,这是因为TCP客户进程发送的第一个TCP报文段的序号为x,所以TCP客户进程发送的第二个报文段的序号为x+1(SYN字段报文需要消耗一个序号)
  • 确认号字段ack被设置为y+1,这是对TCP服务器进程所选择的初始序号的确认

请注意:TCP规定普通的TCP确认报文段可以携带数据,但如果不携带数据,则不消耗序号

image.png

TCP服务器进程收到该确认报文段后也进入连接已建立状态 现在,TCP双方都进入了连接已建立状态,它们可以基于已建立好的TCP连接,进行可靠的数据传输

这里有一个问题:
为什么TCP客户进程最后还要发送一个普通的TCP确认报文段?能否使用“两报文握手”建立连接?
答案是否定的。

  • 三次握手建立连接是为了防止已经失效的连接请求报文段突然又传到服务端,产生错误

下图实例是“两报文握手”
image.png

客户端发出去了第一个连接请求报文并没有丢失,但是由于某种原因造成了较长时间的迟到现象

此时发送端重新开始发送请求连接报文,并且通过两次握手成功建立连接,没有进行请求序号的验证

在传输完数据之后,通过四次挥手释放连接。此时双方处于关闭连接状态

但是此时,已经迟到多时的请求报文到达了服务器,本来这是一个早已失效的报文段,但是服务器收到此失效的报文之后,会误认为是客户端再次发出的一个新的连接请求

于是服务器就向客户端又发出确认报文,表示同意建立连接。此时服务器处于连接状态,而客户端由于处于关闭状态,不会接收该确认报文。

如果不采用“三次握手”服务端接收到客户端发出的请求报文就会认为要请求建立新的连接,并且进入连接状态,但是客户端此时可能并没有发出建立连接的请求,该报文是由于某种情况迟到的请求,因此不会去向B端发送数据,服务端没有收到数据就会一直等待

这样子会造成服务端白白浪费掉很多资源。

综上所诉,三次握手并不多余,这是为了防止已失效的连接请求报文段突然又传送到了TCP服务器,因而导致错误。

总结

image.png
image.png