TCP协议详解
这篇文章以抓包验证为主线,对 TCP 从“协议语义、首部字段、连接状态到拥塞控制”做了系统化拆解。TCP与UDP差异及TCP语义首先明确 TCP 的三大特性:面向连接、字节流、可靠传输。通过“读写次数不对应”解释字节流本质,并与 UDP 报文边界语义对比。可靠性机制包含确认应答、超时重传、乱序重排与去重后再交付应用层。…
本文章为《Linux高性能服务器编程》第四章的笔记,该书描述该章的各种内容的时候,几乎都使用了实践的工具来抓包验证并解释的方式来铺开知识点。我这里几乎是照搬了书本的知识点,但做了个分类处理。TCP协议 在详细讨论TCP协议之前,我们先简单介绍一下TCP服务的特点,以及它和UDP服务的区别。 传输层协议主要有两个:TCP协议和UDP协议。TCP协议相对于UDP协议的特点是:面向连接、字节流和可靠传输。 面向连接: 使用TCP协议通信的双方必须先建立连接,然后才能开始数据的读写。双方都必须为该连接分配必要的内核资源,以管理连接的状态和连接上数据的传输。TCP连接是全双工的,即双方的数据读写可以通过一个连接进行。完成数据交换之后,通信双方都必须断开连接以释放系统资源。 字节流: 字节流服务和数据报服务的接收双方的最终表现出来的区别是,通信双方是否必须执行相同次数的读、写操作。具体原因在于,TCP通信是有接收和发送缓冲区的,应用程序可以一次性将TCP接收缓冲区中的数据全部读出,也可以分多次读取,这取决于用户指定的应用程序读缓冲区的大小。因此,应用程序执行的读操作次数和TCP模块接收到的TCP报文段个数之间也没有固定的数量关系。 综上所述,发送端执行的写操作次数和接收端执行的读操作次数之间没有任何数量关系,这就是字节流的概念:应用程序对数据的发送和接收是没有边界限制的。UDP则不然。发送端应用程序每执行一次写操作,UDP模块就将其封装成一个UDP数据报并发送之。接收端必须及时针对每一个UDP数据报执行读操作(通过recvfrom系统调用),否则就会丢包(这经常发生在较慢的服务器上)。并且,如果用户没有指定足够的应用程序缓冲区(程序开发者自建的)来读取UDP数据,则UDP数据将被截断。 图3-1和图3-2显示了TCP字节流服务和UDP数据报服务的上述区别。两图中省略了传输层以下的通信细节。 TCP和UDP对比 可靠传输:TCP协议采用发送应答机制,即发送端发送的每个TCP报文段都必须得到接收方的应答,才认为这个TCP报文段传输成功。TCP协议采用超时重传机制,发送端在发送出一个TCP报文段之后启动定时器,如果在定时时间内未收到应答,它将重发该报文段。因为TCP报文段最终是以IP数据报发送的,而IP数据报到达接收端可能乱序、重复,所以TCP协议还会对接收到的TCP报文段重排、整理,再交付给应用层。 UDP协议则和IP协议一样,提供不可靠服务。它们都需要上层协议来处理数据确认和超时重传。TCP头部信息TCP头部信息清单 TCP头部结构如图3-3所示,其中的诸多字段为管理TCP连接和控制数据流提供了足够的信息。 TCP头部结构16位端口号(port number) 告知主机该报文段是来自哪里(源端口)以及传给哪个上层协议或应用程序(目的端口)的。 进行TCP通信时,客户端通常使用系统自动选择的临时端口号,而服务器则使用知名服务端口号。32位序号(sequence number) 一次TCP通信(从TCP连接建立到断开)过程中某一个传输方向上的字节流的每个字节的编号。 假设主机A和主机B进行TCP通信,A发送给B的第一个TCP报文段中,序号值被系统初始化为某个随机值ISN(InitialSequence Number,初始序号值)。那么在该传输方向上(从A到B),后续的TCP报文段中序号值将被系统设置成ISN加上该报文段所携带数据的第一个字节在整个字节流中的偏移。例如,某个TCP报文段传送的数据是字节流中的第1025~2048字节,那么该报文段的序号值就是ISN+1025。另外一个传输方向(从B到A)的TCP报文段的序号值也具有相同的含义。32位确认号(acknowledgement number) 用作对另一方发送来的TCP报文段的响应。其值是收到的TCP报文段的序号值加1。 假设主机A和主机B进行TCP通信,那么A发送出的TCP报文段不仅携带自己的序号,而且包含对B发送来的TCP报文段的确认号。反之,B发送出的TCP报文段也同时携带自己的序号和对A发送来的报文段的确认号。4位头部长度(header length) 标识该TCP头部有多少个32bit字(4字节)。因为4位最大能表示15,所以TCP头部最长是60字节。6位标志位 ❑URG标志,表示紧急指针(urgent pointer)是否有效。 ❑ACK标志,表示确认号是否有效。我们称携带ACK标志的TCP报文段为确认报文段。 ❑PSH标志,提示接收端应用程序应该立即从TCP接收缓冲区中读走数据,为接收后续数据腾出空间(如果应用程序不将接收到的数据读走,它们就会一直停留在TCP接收缓冲区中)。 ❑RST标志,表示要求对方重新建立连接。我们称携带RST标志的TCP报文段为复位报文段。 ❑SYN标…
正在初始化 WebAssembly 引擎…
首次编译原生模块可能需要数秒
就绪后,页面交互将以接近原生的速度运行