当前位置: 首页 > news >正文

TCP数据报

三次握手Three-Way Handshake

TCP 协议中用于建立可靠连接的过程。通过三次握手,客户端和服务器能够确认彼此的存在,并且同步各自的初始序列号,为后续的数据传输做好准备。三次握手确保了双方在正式传输数据前能够建立一个可靠的连接。

三次握手的步骤:

  1. 第一次握手(客户端 -> 服务器):

    • 客户端发送一个 SYN(同步)请求数据包,表示希望与服务器建立连接。客户端选择一个初始序列号(ISN,Initial Sequence Number),并将其附带在请求包中。

    • 数据包内容

      • SYN = 1:表示请求建立连接。

      • seq = x:表示客户端选择的初始序列号。

    这时,客户端的状态为 SYN_SENT(已发送连接请求)。

  2. 第二次握手(服务器 -> 客户端):

    • 服务器收到客户端的 SYN 包后,如果同意连接,会发送一个带有 SYNACK(确认)标志的数据包作为响应。服务器也会选择自己的初始序列号,并将客户端的序列号加1作为 ACK 值,确认收到客户端的请求。

    • 数据包内容

      • SYN = 1:表示服务器同意建立连接。

      • ACK = 1:表示确认客户端的请求。

      • seq = y:表示服务器选择的初始序列号。

      • ack = x + 1:表示确认收到客户端的序列号(客户端的初始序列号加 1)。

    服务器的状态变为 SYN_RECEIVED(接收到连接请求)。

  3. 第三次握手(客户端 -> 服务器):

    • 客户端收到服务器的 SYN+ACK 包后,向服务器发送一个确认包,表示自己已准备好数据传输。客户端将服务器的序列号加1作为 ACK 值,确认服务器的序列号。

    • 数据包内容

      • ACK = 1:表示确认服务器的响应。

      • seq = x + 1:表示客户端的序列号加 1。

      • ack = y + 1:表示确认收到服务器的序列号(服务器的初始序列号加 1)。

    客户端的状态变为 ESTABLISHED(连接已建立)。

  4. 连接建立完毕:

    • 在第三次握手完成后,客户端和服务器之间的连接建立成功,双方可以开始数据传输。

三次握手的目的:

  1. 确保双方都能接收到对方的序列号:三次握手的过程确保了客户端和服务器都知道彼此的初始序列号,从而可以确保后续数据传输的顺序正确。

  2. 确认双方都准备好进行数据传输:通过交换同步信号(SYN)和确认信号(ACK),双方确认都已经准备好开始数据传输。

  3. 防止旧连接数据的干扰:三次握手通过序列号和确认号的机制,确保旧的连接数据不会干扰新连接的建立。

举个例子:

假设你想和朋友通过电话建立通话,三次握手可以类比为:

  1. 第一次握手:你拨通电话,告诉朋友“我想和你通话”,这就是你发出的 SYN 请求。

  2. 第二次握手:朋友接到电话,确认可以和你通话并说“我也准备好了”,这是朋友发出的 SYN+ACK 响应。

  3. 第三次握手:你听到朋友的回复后确认“好的,我也准备好了,现在开始通话”,这就是你发出的 ACK 确认。

在三次确认后,电话通话就正式开始了,类似于 TCP 连接的建立完成,双方可以开始交换数据。

  0                   1                   2                   30 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+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|          源端口号(16位)     |        目标端口号(16位)     |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|                        序列号(32位)                         |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|                      确认号(32位)                          |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| 数据偏移 |保留|URG|ACK|PSH|RST|SYN|FIN|     窗口大小(16位)  |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|         校验和(16位)        |       紧急指针(16位)        |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|                        可选项(可变)                         |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|                          数据(可变)                         |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

字段长度(位)说明
源端口号(Source Port)16发送方应用程序的端口号
目的端口号(Destination Port)16接收方应用程序的端口号
序列号(Sequence Number)32本段数据的第一个字节在整个字节流中的编号
确认号(Acknowledgment Number)32期望接收的下一个字节的序号(如果ACK标志置位)
数据偏移(Data Offset)4TCP首部长度(以4字节为单位)
保留(Reserved)3保留,置0
控制位(Flags)9标志位(URG, ACK, PSH, RST, SYN, FIN等)
窗口大小(Window Size)16告诉对方自己还能接收多少字节
校验和(Checksum)16用于检验数据在传输过程中是否出错
紧急指针(Urgent Pointer)16如果URG位为1,表示紧急数据的结束位置
选项(Options)可变可选字段,比如窗口扩大因子、时间戳等
填充(Padding)可变为了保证TCP首部是32位(4字节)对齐

序列号

假设发送方的初始序列号是 1000,发送了以下 4 个数据段:

  • 第一个数据段,发送字节 1 到字节 1000,序列号为 1000。

  • 第二个数据段,发送字节 1001 到字节 2000,序列号为 1001。

  • 第三个数据段,发送字节 2001 到字节 3000,序列号为 2001。

  • 第四个数据段,发送字节 3001 到字节 4000,序列号为 3001。

确认号

确认号的作用:

  1. 确认数据接收:接收方通过确认号告诉发送方,它已经成功接收了哪些数据。比如,如果接收方成功接收到序列号为 1000 到 1007 的数据,接收方会返回一个确认号 1008,表示它希望接收下一个序列号为 1008 的数据。

  2. 丢包检测:如果发送方在一定时间内没有收到确认号,它就知道可能发生了数据丢失,会重新发送数据。比如,如果发送方在规定时间内没收到确认号 1008,它就会重发序列号为 1000 到 1007 的数据。

  3. 确保数据顺序:即使数据包乱序到达,接收方也能通过确认号告诉发送方下一个期望的字节序列号,让发送方知道数据是否按顺序到达。

举个例子:

假设你发送的数据的序列号是从 1000 开始:

  • 你发送了字节 1000 到 1007 的数据,接收方收到这些数据后,它会返回一个确认号 1008,表示接收方已经成功接收了序列号小于 1008 的数据,期待下一个序列号为 1008。

  • 如果接收方只收到字节 1000 到 1003,未收到字节 1004 到 1007,它会继续等待并不会返回 1008,而是会继续要求重传缺失的部分,直到接收到完整的数据。

数据偏移(Data Offset)

TCP 头部中的一个字段,用来指示 TCP 头部的长度,即数据部分从哪里开始 。数据偏移字段是一个 4 位的数,表示 TCP 头部的长度,单位是 32 位(4 字节)

假设你有一个 TCP 数据包,它的 数据偏移 值为 5,表示 TCP 头部的长度是 5 × 4 = 20 字节。这意味着接收方应该从数据包的第 21 字节开始读取实际的数据部分。

如果数据偏移值为 6,表示 TCP 头部的长度是 6 × 4 = 24 字节,那么数据就从数据包的第 25 字节开始。

SYN

是 TCP 报文头中的一个标志位,全称是 Synchronize(同步),它用于 建立连接时同步双方的初始序列号,是 TCP 三次握手 中的重要部分。


✅ 通俗解释:

你可以把 SYN 理解为:“你好,我想和你建立连接,这是我的号码(初始序列号)。”

当两台设备通过 TCP 通信时,它们必须先通过 三次握手 确认彼此都准备好了,并知道对方的“起始编号”,这个编号就是通过 SYN 标志的报文来传递的。


🔁 SYN 在三次握手中的作用:

  1. 第一次握手:客户端发送一个 SYN=1 的报文,告诉服务器:“我想建立连接,我的初始序列号是 X。”

  2. 第二次握手:服务器回复一个 SYN=1 + ACK=1 的报文,说:“我同意连接,我的初始序列号是 Y,同时确认你的是 X+1。”

  3. 第三次握手:客户端再发送一个 ACK=1 报文,确认服务器的序列号 Y+1,连接建立。

URG(Urgent Pointer)

TCP 头部中的一个标志位,表示该数据段包含紧急数据。它与 紧急指针(Urgent Pointer) 一起使用,用来告知接收方数据中的某一部分是紧急的,需要优先处理。

假设一个 TCP 数据段的 URG 标志位 为 1,紧急指针为 500。这个意味着接收方应该优先处理从数据段开始到第 500 字节之间的数据(包含第 500 字节)。然后,接收方可以继续处理剩下的普通数据。

FIN

是 TCP 协议中的一个控制标志位,全称是 Finish(结束),表示“我已经没有数据要发送了,但我还可以接收你的数据”。

它用于 TCP连接的释放阶段,也就是我们常说的 “四次挥手” 中,FIN 标志就是“挥手”的信号。

TCP 四次挥手中 FIN 的使用过程:

  1. 第一次挥手(客户端发送 FIN):
    客户端想关闭连接,向服务器发送一个带 FIN=1 的数据包,告诉服务器“我已经发完了,你可以关我这边的发送通道”。

  2. 第二次挥手(服务器回 ACK):
    服务器收到 FIN 后,发送一个 ACK 包,表示“我知道了,但我可能还有数据要发,等我发完再说”。

  3. 第三次挥手(服务器发送 FIN):
    等服务器也没有数据可发了,就发送一个带 FIN=1 的数据包给客户端,请求关闭它的发送通道。

  4. 第四次挥手(客户端回 ACK):
    客户端收到后回复 ACK,连接彻底断开。客户端会进入一个叫 TIME_WAIT 的状态,等一段时间确保服务器收到了 ACK,才真正关闭连接。


📌 举个例子:

你和朋友打电话,说完自己的话后,你说:“我说完了(FIN)。”
朋友听到后回答:“我知道了(ACK)。”
然后朋友继续说他的内容,说完后他说:“我也说完了(FIN)。”
你听到后说:“好的,我也知道了(ACK)。”
这时你们才挂掉电话。

窗口大小Window Size

是 TCP 协议中一个非常关键的概念,它表示接收方能够一次接收、缓存但尚未确认的数据量,单位是字节(Bytes)。


✅ 通俗解释:

你可以把窗口大小想象成水杯的容量,而发送方的数据就像水。发送方可以往水杯里倒水(发数据),但不能超过杯子的容量(窗口大小),否则水会溢出(接收方缓存不下)。

所以,窗口大小的作用是:

  • 告诉发送方:“我现在还能接收这么多数据,请别一下子发太多。”

  • 控制数据发送速率,防止接收方来不及处理,造成数据丢失。

  • 实现 TCP 的 流量控制(Flow Control)


📦 举例说明:

假设你是接收方,你告诉对方:“我的窗口大小是 3000 字节。”
发送方就知道:“好,那我最多能连续发 3000 字节的数据,不等确认。”
一旦你确认了收到一部分数据,比如确认了 1000 字节,窗口就又打开了 1000 字节,发送方就可以继续发。

 

校验和(Checksum)

是 TCP/IP 协议中用于检验数据在传输过程中是否出错的一种机制。它的主要作用是:接收方可以通过计算校验和,判断收到的数据有没有在网络中被损坏


✅ 通俗解释:

你可以把校验和想象成是“打包清单的总和”。
比如你寄一个包裹给朋友,里面有10样东西,你在单子上写:“这10样东西的总价值是100元”。
朋友收到包裹后,把每件物品的价格加起来,如果加出来也是100元,就知道东西没少;如果不是,就说明包裹中途出了问题。

TCP/UDP/IPv4 中的校验和也是这个道理。


🔧 在 TCP 中怎么用?

  1. 发送方在发数据前,会对整个 TCP 头部 + 数据 做一个运算,得出一个 16 位的校验值,填入 TCP 头部的“校验和字段”中。

  2. 接收方收到数据后,用相同的算法重新计算一遍校验和:

    • 如果和报文中的校验和一致,说明数据是完整的;

    • 如果不一致,说明数据在传输过程中发生了错误(如被干扰、电磁噪声破坏等),就会丢弃这个包。


✍️ 校验和的特点:

  • 属于一种 差错检测机制,但不能纠正错误(不是纠错码)。

  • IPv4、TCP、UDP 都使用校验和;IPv6 中 IP 层没有校验和,但 TCP/UDP 仍使用。

  • TCP 校验和还包括一个“伪首部”(Pseudo Header),包含源 IP、目标 IP、协议号、数据长度等,用于增强安全性。


📌 举个例子(简化):

  • 数据部分是:0x1234, 0x5678, 0x9abc

  • 发送方加起来得到:0x1234 + 0x5678 + 0x9abc = 0x10168

  • 把这个结果“反码取反”,得出校验和 0xFE97,放进报文中。

  • 接收方收到数据后再加一遍,再加上 0xFE97,结果应该是 0xFFFF(这是正确的标志)。

ACK

是 TCP 报文头中的一个标志位,全称是 Acknowledgment(确认),表示**“确认收到数据”**或“确认连接建立”。


✅ 通俗解释:

你可以把 ACK 理解成:“我收到了你发的数据/请求,这是我的确认回应。

在 TCP 通信中,每当一方收到数据后,都会用 ACK 来告诉对方:“我收到了,从这个序号之后你可以继续发。”


🧩 ACK 的作用包括:

  1. 三次握手中用于确认连接请求

    • 客户端发送 SYN,服务器回复 SYN + ACK,表示“我同意并确认你的请求”。

  2. 数据传输中确认收到

    • 每当一段数据被成功接收,接收方就会发出 ACK 报文,告诉发送方:“你前面发的数据我收到了,请继续。”

  3. 用于可靠传输机制

    • TCP 是可靠协议,靠 ACK 来保证“发的每一段数据都能被确认”,丢了就会重发。


🔁 举个例子:

  • 客户端发送数据,序列号为 100;

  • 服务器收到后,回复一个 ACK=101,意思是:“我已经收到100这个字节,接下来从101开始继续发。”

相关文章:

  • 开发积分商城为商家带来的多重优势
  • 2.4线性方程组
  • CAN通信
  • Twin Builder 中的电池等效电路模型仿真
  • 如何在 Vue3 中更好地使用 Typescript
  • 【计算机网络 第8版】谢希仁编著 第四章网络层 地址类题型总结
  • Spring Boot操作MongoDB的完整示例大全
  • 《算法导论(第4版)》阅读笔记:p9-p9
  • OSCP - Proving Grounds - NoName
  • P1782 旅行商的背包 Solution
  • vue3在使用@import “./index.scss“报错
  • 用 GRPO 魔法点亮Text2SQL 的推理之路:让模型“思考”得更像人类
  • FastJson 转 Jackson 指南
  • Codeforces Round 1023 (Div. 2) ABC
  • 一种基于条件生成对抗网络(cGAN)的CT重建算法
  • 美团Java高级配送员面经分享|玩梗版
  • Xshel工具介绍
  • 提示词优化:检索历史提示确定方向→生成候选提示并控制修改幅度→基于准确率迭代优化
  • 前端流行框架Vue3教程:14. 组件传递Props效验
  • Java工具学习
  • 世界银行最新营商环境体检单:59个测评点,上海22项达全球最优水平
  • 市场监管总局发布《城镇房屋租赁合同(示范文本)》
  • 世界羽联主席巴达玛:中国组织赛事的能力无与伦比
  • 上海成五一国内最热门的入境游目的地,国际消费明显提升
  • 巴菲特掌舵伯克希尔60年后将卸任CEO,库克:认识他是人生中最珍贵的经历之一
  • 乌美签署矿产协议