TCP 三次握手过程中客户端发送的 SYN 报文的基本结构

发布时间 2023-04-23 13:52:22作者: 习久性成

**以下是 SYN 报文示意图,展示了 TCP 三次握手过程中客户端发送的 SYN 报文的基本结构**。

```
Segment Header
+----------------+------------------------------+
| IP Header | TCP Header |
+----------------+------------------------------+
| Source Address | Destination Address |
+----------------+------------------------------+
| Source Port | Destination Port |
+----------------+------------------------------+
| Sequence Number ( ISN ) |
+------------------------------------------------+
| Acknowledgment Number |
+------------------------------------------------+
| Data offset | Reserved | Flags | Window |
+----------------------+--------+----------------+
| Checksum | Urgent Pointer |
+----------------------+---------------------------+
| Options |Padding|
+---------------------------+--------+--------+-----+

```

其中,重要字段包括:

- **源地址(Source Address)** 和 **目的地址(Destination Address)**:指明数据包的源和目标计算机地址。
- **源端口号(Source Port)** 和 **目标端口号(Destination Port)**:指明数据包的源和目标进程端口号。
- **序列号(Sequence Number)**:指明此报文段所发送的第一个字节的编号(ISN)。
- **ACK 号(Acknowledgment Number)**:表示接收方期望的下一个序列号。在 SYN 报文中无数据,ACK 号设置为 0。
- **TCP 标志位(Flags)**:SYN(Synchronize)标志,用于请求建立连接。
- **窗口大小(Window Size)**:表示接收方可处理的未经确认的字节数量,可以动态调整。
- **选项(Options)**:可选字段,用于在报文中加入各种控制信息。

以上是 TCP SYN 报文的基本结构。在建立连接时,客户端将 SYN 标志位置为1,同时随机选择序列号并发送给服务器。这样就使得每次建立连接的序列号都不同,从而增加了系统安全性。

以下是建立 TCP 连接后的数据传输图,展示了客户端和服务器之间通过 TCP 协议进行通信的过程。假设客户端发送了一段文本信息给服务器。

  1. 客户端首先封装要发送的数据为 TCP 报文,并设置序列号(SN)和 ACK 号(AN),表示待发送数据的编号和期望收到确认报文的编号。然后将报文发送给服务器。
Client                                           Server

  |                                               |
  |    SN = X    AN = Y                           |
  | ---------------------------------------------->|
  |                                               |
  1. 服务器接收到客户端发送过来的 TCP 报文后,检查有效性并确认已经接收到数据,将该数据包作为下一个要接收的字节,并返回一个 ACK 报文确认客户端发送的TCP报文已经接收到。ACK 报文中的 ACK 号等于客户端发送的序列号 + 数据长度。
Client                                           Server

  |                                               |
  |    SN = X    AN = Y                           |
  | ---------------------------------------------->|
  |                                               |
  |              AN = X+length                    |
  | <-----------------------------------------------|
  |                                               |
  1. 当服务器收到客户端的最终数据时,服务器也会向客户端发送一个 FIN 报文,表示不再发送数据,也意味着服务器将会关闭这个连接。
Client                                           Server

  |                                               |
  |    SN = X    AN = Y                           |
  | ---------------------------------------------->|
  |                                               |
  |              AN = X+length                    |
  | <-----------------------------------------------|
  |                                               |
  |              AN = X+length    FIN              |
  | <-----------------------------------------------|
  |                                               |
  |                                               |
  |    SN = Y          ACK=X+length       ACK/FIN  |
  | ---------------------------------------------->|
  |                                               |

  1. 当客户端收到 FIN 报文时,向服务器发送一个 ACK 应答报文,表示确认收到了 FIN 报文。此时,客户端进入半关闭状态,即只能接收数据,不能再发送数据。
Client                                           Server

  |                                               |
  |    SN = X    AN = Y                           |
  | ---------------------------------------------->|
  |                                               |
  |              AN = X+length                    |
  | <-----------------------------------------------|
  |                                               |
  |              AN = X+length    FIN              |
  | <-----------------------------------------------|
  |                                               |
  |    SN = Y          AN = X+length     ACK      |
  | ---------------------------------------------->|
  |                                               |
  1. 最后,当服务器接收到客户端的 ACK 报文时,也进入半关闭状态。在服务器等待客户端的数据都传输完成之后,服务器就会完全关闭连接。在整个过程中,TCP 保证了数据在传输过程中的正确性和可靠性。

一次完整的 HTTP 数据请求过程通常包括以下几个步骤:

  1. 域名解析:当用户输入一个域名后,首先需要把该域名解析成对应的 IP 地址。这个解析过程通常由本地 DNS 或者运营商 DNS 完成。

  2. 建立 TCP 连接:客户端向服务器发起连接请求三次握手,建立TCP连接。

  3. 发送 HTTP 请求:客户端向服务器发送 HTTP 请求报文,在报文中包含请求方法、URI、协议版本、请求头等信息。

  4. 服务器响应:服务器接收到请求后,做出相应处理并返回 HTTP 响应报文,报文中包含协议版本、状态码、响应头部和响应正文等信息。

  5. 接收响应内容:客户端接收到服务器返回的 HTTP 响应后,进行处理和资源加载,例如通过浏览器渲染页面。

  6. 断开连接:在完成数据传输后,客户端和服务器都可通过四次挥手断开连接。

总结来说,一次完整的 HTTP 数据请求过程分为请求阶段和响应阶段,其中请求阶段包括建立 TCP 连接和发送 HTTP 请求两个步骤,响应阶段包括服务器响应和接收响应内容两个步骤,最后是断开连接。在每个阶段中,各个环节都需要按照协议规范进行处理,以保证整个过程的正确性和可靠性。

是的,HTTP(Hypertext Transfer Protocol)是基于 TCP(Transfer Control Protocol)协议实现的。

在进行 HTTP 通信时,客户端和服务器之间需要先建立一条 TCP 连接,然后再通过这条连接传输 HTTP 消息。TCP 提供了面向连接的、可靠的字节流服务,保证了数据传输的准确性和完整性,而 HTTP 使用 TCP 传输层的特性,可以在此基础上更高效地传输数据。

在每次 HTTP 请求发送过程中,都需要先建立一个 TCP 连接,以确保客户端和服务器之间的通信是可靠和有序的。建立连接后,客户端会向服务器发送具体的 HTTP 请求信息(例如请求方法、URI、协议版本等等),服务器收到请求后才能针对该请求做出响应。

因此,在一次完整的 HTTP 请求过程之前,客户端与服务器之间必须先建立 TCP 连接,这样才能保证客户端和服务器之间的信息能够准确无误地传递与处理。

TCP 建立连接并发送数据通常包括三个步骤。

  1. 第一次握手(Syn):客户端向服务器发出 Syn 报文,请求建立新连接。在该报文中,客户端随机选择序列号,并设置 SYN 标志位为 1。

  2. 第二次握手(Syn + Ack):服务器收到客户端的 SYN 报文后,回复一个 ACK 应答报文,表示确认已经收到客户端的请求。同时服务器也发送自己的 SYN 报文,并将确认序列号 ACK 设置为客户端发送过来的序列号加 1。

  3. 第三次握手(Ack):客户端接收到服务器返回的 SYN-ACK 报文后,再次回复一个 ACK 应答报文,以确保双方都能够正常通信,此时客户端和服务器之间的 TCP 连接就建立成功了。之后客户端和服务器就开始互相发送和接收数据,每一个报文都具有一个单独的序列号。

TCP 建立连接成功后的数据传输过程:

  • 发送方给待发送数据打上序列号并封装成 TCP 报文进行传输。
  • 收到数据的接收方接收到TCP 报文后对数据进行校验和提取,判断是否有丢失或错误,如果有则会重新请求数据进行传输。
  • 接收方确定收到正确的数据后,发送 ACK(确认应答)报文对数据包进行确认,并回复下一个字节期望接收的字节数,即接收方序列号。
  • 发送方等待 ACK 应答,如果超时还未收到,则会重传数据,确保可靠性。

这样就保证了 TCP 数据传输的正确性、完整性和可靠性。

TCP(传输控制协议)报文的格式如下

   0                   1                   2                   3
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |          Source Port          |       Destination Port        |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                        Sequence Number                        |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                    Acknowledge Number                         |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  | Data |           |U|A|P|R|S|F|                               |
  | Offset| Reserved  |R|C|S|S|Y|I|             Window            |
  |       |           |G|K|H|T|N|N|                               |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |           Checksum            |         Urgent Pointer         |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                    Options                    |    Padding    |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |                             data                              |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

TCP 报文通过头部信息和数据等字段传输数据。其中 TCP 报文头包括以下几个字段:

  • 源端口号(Source Port)和目标端口号(Destination Port):用来标识源主机和目的主机之间的进程。
  • 序列号(Sequence Number):用于对每一个字节的数据进行编号,保证数据传输顺序的正确性。
  • 确认号(Acknowledge Number):发送方期望收到对应 ACK 应答报文的最后一个字节的编号。
  • 数据偏移量(Data Offset):指示报文头长度,用于识别数据是否在哪里开始。
  • 控制标志(Flags):包括 URG(紧急指针有效)、ACK(确认应答有效)、PSH(立即将数据推送给接收方)、RST(复位连接)、SYN(同步序列号)、FIN(终止连接)等标志。
  • 窗口大小(Window):用于流量控制,告诉对端本地缓存有多少个字节可以接收。
  • 校验和(Checksum):用于检验 TCP 报文是否损坏,防止数据出现错误时被传输。
  • 紧急指针(Urgent Pointer):表示紧急数据的边界。
  • 选项(Options):可选择性地传递扩展信息的字段,例如 TCP 时间戳、窗口调整因子等。

TCP 报文结构中还包含了 padding 和 data 字段,它们分别用来占用报文部分或者携带传输的数据。