前言
在计算机网络协议栈中,传输层 位于网络层和应用层之间,主要负责端到端的可靠通信。**TCP(传输控制协议)**作为最常用的传输协议,承载了很多核心应用,如 HTTP、FTP 等。
本文将从 TCP 头部结构、三次握手过程、连接建立问题、重传机制等多个维度,详细解析 TCP 协议的工作原理,帮助读者更好地理解其在网络中的作用和实现机制。
一、TCP 的头部结构
TCP 头部字段
TCP 头部是 TCP 协议的数据包的开始部分,它包含了控制信息和标识符,通常为 20 字节的固定长度,最多可以扩展到 60 字节。以下是 TCP 头部的重要字段:
-
序列号(Sequence Number):用于标识数据流中字节的顺序,是每个 TCP 数据包的唯一标识符。客户端和服务器在数据传输过程中都会依赖序列号来确认数据是否正确到达。
-
确认号(Acknowledgment Number) :用于接收方告知发送方,已经成功接收到的数据字节的下一个序号。确认号是 接收方序列号 的下一个字节。
-
标志位(Flags):
-
SYN(同步):用于建立连接,表示要发起连接请求。
-
ACK(确认):确认数据包接收成功。
-
FIN(结束):表示数据传输完成,连接即将关闭。
-
RST(重置):用于重置连接。
-
PSH(推送):告诉接收方立即处理数据,不进行缓冲。
-
URG(紧急):表示数据包含紧急信息,需优先处理。
-
-
窗口大小(Window Size):告知对方当前接收方的缓冲区大小,用于流量控制。
-
校验和(Checksum):用于数据完整性检查,确保数据在传输过程中没有错误。
-
紧急指针(Urgent Pointer):指示紧急数据的位置。
二、TCP 三次握手过程
TCP 三次握手
TCP 连接的建立需要经过 三次握手,这个过程用于确保客户端和服务器之间建立可靠的通信通道。
第一次握手(SYN)
-
客户端向服务器发送 SYN 包,表示请求建立连接。
-
该包中包含一个初始的 序列号(ISN) ,例如
Seq = x。
第二次握手(SYN + ACK)
-
服务器收到客户端的 SYN 包后,回应一个 SYN+ACK 包,表示同意建立连接。
-
该包的 确认号(ACK) 为客户端的 序列号 + 1 (
Ack = x + 1)。 -
同时,服务器也会发送自己的初始序列号
Seq = y。
第三次握手(ACK)
-
客户端收到服务器的 SYN+ACK 包后,回应一个 ACK 包,表示连接建立成功。
-
该包的 确认号(ACK) 为服务器的序列号 + 1(
Ack = y + 1)。
到此为止,TCP 连接建立完毕,数据可以开始传输。
三、关于 TCP 三次握手中可能发生的问题
客户端第三次确认包丢失
如果客户端发送的 第三次 ACK 包 丢失,服务器会等待一段时间后再次发送 SYN+ACK 包。客户端收到后会重新发送 ACK 包,从而完成握手。
服务端第二次报文后连接状态
在服务器发送第二个 SYN+ACK 包后,连接状态处于 SYN_RCVD 状态,等待客户端的 ACK 包。如果没有收到客户端的 ACK ,则会重新发送 SYN+ACK 包。
三次握手与 accept 的关系
在服务器端,accept 系统调用会在三次握手完成后被触发。accept 会做以下工作:
- 从操作系统的连接队列中获取已完成的连接请求
- 创建一个新的套接字用于与客户端通信
- 为新的连接分配资源
客户端发送的 SYN 报文服务器没有收到怎么办?
如果服务器没有收到客户端的 SYN 报文,客户端会在超时后重发 SYN 包。通常,客户端会进行 重试,直到连接成功或达到最大重试次数。
服务器收到 SYN+ACK 丢失怎么办?
如果服务器发送的 SYN+ACK 包丢失,客户端会在超时后重新发送 SYN 包,继续三次握手。服务器会再次响应 SYN+ACK 包。
客户端重传 SYN 报文,服务器收到重复的 SYN 包怎么办?
服务器会忽略重复的 SYN 包,并且根据 序列号 和 确认号 确认是否是有效的连接请求。如果重复的 SYN 包是合法的,服务器将再次发送 SYN+ACK 包。
服务端内部工作(第一次握手)
当客户端发送 SYN 包时,服务器在内部执行以下操作:
- 创建一个 TCP 连接 对象
- 选择一个 初始序列号(ISN)
- 为连接分配资源,准备进入 SYN_RCVD 状态
四、TCP 三次握手过程中的其他问题
大量 SYN 包发送给服务器时会发生什么?
当收到大量的 SYN 包时,服务器可能会面临 SYN 洪水攻击 。服务器会为每个连接分配资源,导致内存资源耗尽、网络负载过大、CPU 占用升高。为防止这种攻击,服务器可以使用 SYN Cookie 技术,或者设置连接队列的大小来限制并发连接。
如何通过抓包看 TCP 连接过程?
使用工具(如 Wireshark 或 tcpdump)抓取数据包,分析 TCP 连接过程:
-
过滤出 SYN 、SYN+ACK 、ACK 包。
-
查看每个包中的 序列号 和 确认号。
-
验证三次握手是否顺利完成。
通过抓包可以精确分析每个阶段的执行情况,帮助排查连接问题。
总结
理解 TCP 三次握手过程及其背后的原理,是理解计算机网络中传输层的关键。在排查网络问题时,特别是在建立连接或高并发情况下,掌握这些原理能够帮助你更高效地定位和解决问题。
总结要点:
- TCP 头部:包含了序列号、确认号、标志位等核心信息,保证了数据传输的可靠性。
- 三次握手:保证客户端与服务器之间的连接可靠、稳定。
- 连接过程中的常见问题:包括包丢失、重传、服务器状态等,了解这些问题有助于提高故障排查效率。