TCP 传输控制协议(二、连接管理)

TCP连接包括启动、数据传输和退出三个阶段,通过三次握手建立连接,四次挥手关闭连接。TCP快启(TCP Fast Open)使用Cookie减少建立连接的步骤。关闭连接时,客户端在TIME_WAIT状态等待2MSL以确保连接完全关闭,防止旧数据干扰新连接。TCP选项如MSS、SACK和时间戳用于优化数据传输和确认。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

TCP 传输控制协议(二、连接管理)

引言

TCP是一种面向连接的单播协议。在数据交换之前,双方必须先建立连接。TCP的服务模型是一个字节流。TCP会修复下层(如IP层,链路层等)产生的数据传输问题,对于数据交换来说,大致有三个方面的问题:丢包、重复和错误。为了解决这些问题,TCP引入了连接的概念。***可以说,UDP和TCP本质上最大的区别在于TCP需要维护连接。TCP由于要维护连接所以TCP是有状态的,相比于无状态的UDP,TCP在妥善处理多种TCP状态问题时需要面对大量的细节问题,比如连接的建立、终止和重启。这一章我们就来一起讨论关于TCP的连接管理。

TCP连接的建立与终止

一个TCP连接是有一个4元组构成的,简单来说就是一组IP和一组端口号。一个TCP连接通常分为三个阶段:启动、数据传输和退出。下面我们就对这三个阶段一步步讨论。

Imgur

​ 图 1

在图1中的时间轴描绘了一个连接建立过程中的相关事宜。

连接建立

正常的连接建立流程(三次握手)

首先我们先讨论一个TCP连接建立的过程:

  1. 客户端发送一个SYN报文段,并指明自己想要连接的端口和它的客户端初始序列号(记为ISN©)。通常客户端还会借此发送一个或多个选项。客户端发送的这个SYN报文段称作段1。这个时候客户端进入SYN-SENT状态

  2. 服务端收到SYN报文段后,进入LISTEN状态。服务端也发送自己的SYN报文段作为相应,并包含了它的 初始序列号(ISN(s))。该段称为段2。为了确认客户的的SYN,服务器将其包含的ISN©数值加1后作为返回的ACK数值,然后进入SYN-RCVD状态。因此,每送一个SYN,序列号就会自动加1。这样如果出现丢失的情况,该SYN段将会重传。

  3. 客户端收到报文后,客户端进入ESTABLISHED状态,这个时候对于客户端来说已经是可以交换数据的状态了。为了确认服务器的SYN,客户的将ISN(s)的数值加1后最为返回的ACK值,这称为段3。

    • 服务端收到后,进入ESTABLISHED状态,这个时候双方就进入正式的数据交换过程。
      TCP A                                                TCP B

  1.  CLOSED                                               LISTEN

  2.  SYN-SENT    --> <SEQ=100><CTL=SYN>               --> SYN-RECEIVED

  3.  ESTABLISHED <-- <SEQ=300><ACK=101><CTL=SYN,ACK>  <-- SYN-RECEIVED

  4.  ESTABLISHED --> <SEQ=101><ACK=301><CTL=ACK>       --> ESTABLISHED

  5.  ESTABLISHED --> <SEQ=101><ACK=301><CTL=ACK><DATA> --> ESTABLISHED

          Basic 3-Way Handshake for Connection Synchronization
 						在[rfc793]中对于三次握手的图示

通过上面这三个报文段就能够正常建立一个TCP连接,也称为三次握手。三次握手的目的不仅在于让通信双方连接一个连接正在建立,还在于利用数据报的选项来交换特殊信息,交换初始序列号ISN。一般来说,三次握手是首个发送SYN的一方被认为主动打开一个连接,我们一般称之为客户端,而被动打开连接的一方我们称之为服务端。但是有一种特殊情况是两个端点同时发起连接,下面会讨论这种特殊的情况。

同时打开 Simultaneous initiation

两个端点同时给对方发送主动建立连接的情况不多见,但是在特定的场景下是有机会出现的。前提是两个端点都有对方的ip和端口,就有可能发生这种情况,对于同时打开,需要四个报文段。

      TCP A                                            TCP B

  1.  CLOSED                                           CLOSED

  2.  SYN-SENT     --> <SEQ=100><CTL=SYN>              ...

  3.  SYN-RECEIVED <-- <SEQ=300><CTL=SYN>              <-- SYN-SENT

  4.               ... <SEQ=100><CTL=SYN>              --> SYN-RECEIVED

  5.  SYN-RECEIVED --> <SEQ=100><ACK=301><CTL=SYN,ACK> ...

  6.  ESTABLISHED  <-- <SEQ=300><ACK=101><CTL=SYN,ACK> <-- SYN-RECEIVED

  7.               ... <SEQ=101><ACK=301><CTL=ACK>     --> ESTABLISHED

                Simultaneous Connection Synchronization

从上面的图可以看出,同时打开每个TCP都是从CLOSED 到 SYN-SENT 再到 SYN-RECEIVED 到已确立的。

这里说一下我个人关于三次握手的一些想法。大家对这个流程想必都不陌生,但是我感觉很多人在描述这个过程的时候并没有说出关键的信息,就是三次握手每次是为了什么。首先握手的目的就是双方确认对方的收发能力,对于两端来说要确认的东西是一样的,确认对方能接受自己的信息,能给自己发送信息。

  • 客户端给服务端发消息的时候,这时候服务端知道客户端有发送消息的能力

  • 服务端给客户端发送消息的时候,客户端就知道服务端有接受消息发送信息的能力

  • 客户端再次给服务端发送消息,这时候服务端就知道客户端有接受信息的能力(通过ACK知道消息是应答而不是重复发)。

不管是哪一端,收到对方的消息就是代表对面有正常发送消息的能力,收到对方的ACK = 己方发送的SEQ + 1就证明对方是有正常的接收能力。

这也很好解释为什么不是四次握手,因为三次握手就已经足够让两端都确认对方有正常的收发消息的能力

当然在三次握手的过程中还处理了很多别的细节问题,不过在我看来,三次握手本质上要做的事情只有一件,就是确认对方的收发能力。

再来看同时打开为什么是四次,其实就是接收到对方正确的ACK回复就

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值