TCP三次握手建立连接
1 概念
传输控制协议(Transmission Control Protocol, TCP),是一种面向连接的、确保数据在端到端可靠传输的协议。
- 面向连接:是指在发送数据前,需要先建立一条虚拟的链路,然后让数据在这条链路上“流动”完成传输。
- 可靠性:为了确保数据的可靠传输,不仅需要对发出的每一个字节进行编号确认,校验每一个数据包的有效性,在出现超时情况时进行重传,还需要通过实现滑动窗口和拥塞控制等机制,避免网络状况恶化而最终影响数据传输的极端情况。
2 TCP 报文格式
每个 TCP 数据包是封装在 IP 包中的,每一个 IP 头的后面紧接着的是 TCP 头,TCP 报文格式如下:
(1)协议第一行的两个端口号各占两个字节,分别表示了源机器端口号和目标机器端口号。这两个端口号与 IP 报头中的源 IP 地址和目标 IP 地址所组成的四元组可唯一识别一条 TCP 连接。
可通过 netstat 命令列出机器上已建立的连接信息,其中包含唯一标识一条连接的四元组,以及各连接的状态等内容。
(2)协议的第二行和第三行是序列号,各占 4 个字节。前者是指所发送数据包中数据部分第一个字节的序号,后者是指期望收到来自对方的下一个数据包中数据部分第一个字节的序列号。
(3)头部长度字段:由于 TCP 报头中存在一些扩展字段,所以需要通过长度为 4 个 bit 的头部长度字段表示 TCP 报头的大小,这样接收方才能准确地计算出包中数据部分开始的位置。
(4)TCP 的 FLAG 位由 6 个 bit 组成,分别代表 SYN、ACK、FIN、URG、PSH、RST,都以置 1 表示有效。我们重点关注 SYN、ACK 和 FIN。
- SYN(Synchronize Sequence Numbers)用作建立连接时的同步信号。
- ACK(Acknowledgement)用于对收到的数据进行确认,所确认的数据由确认序列号表示。
- FIN(Finish)表示后面没有数据需要发送,通常意味着所建立的连接需要关闭了。
3 三次握手
(1)A 机器发出一个数据包并将 SYN 置为 1,表示希望建立连接。这个包中的序列号假设是 x。
(2)B 机器收到 A 机器发过来的数据包后,通过 SYN 得知这是一个建立连接的请求,于是发送一个响应包并将 SYN 和 ACK 标记都置为 1。假设这个包中的序列号是 y,而确认序列号必须是 x+1,表示收到了 A 发过来的 SYN。
(3)A 收到 B 的响应包后需要进行确认,确认包中将 ACK 置为 1,并将确认序列号置为 y+1,表示收到了来自 B 的 SYN。
4 为什么需要三次握手?
它主要有两个目的:信息对等、防止超时。
4.1 保证信息对等
双方只有确定 4 类信息之后,才能建立连接。
4.2 防止请求超时导致脏连接
- 如果两次握手就可以创建连接,重新发送的连接请求传输数据并释放连接后,第一个超时的连接请求才到达 B 机器的话,B 机器会以为是 A 创建新连接的请求,然后确认同意创建连接。因为 A 机器的状态不是 SYN_SENT,所以直接丢弃了 B 的确认数据,以致最后只是 B 机器单方面创建连接完毕。
- 如果是三次握手,则 B 机器收到连接请求后,同样会向 A 机器确认同意创建连接,但因为 A 机器不是 SYN_SENT 状态,所以会直接丢弃,B 机器由于长时间没有收到确认信息,最终超时导致连接创建失败,因而不会出现脏连接。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?