开发者社区> 华章计算机> 正文

《Linux高性能服务器编程》——3.2 TCP头部结构

简介: 本节书摘来自华章计算机《Linux高性能服务器编程》一书中的第3章,第3.2节,作者 游双,更多章节内容可以访问云栖社区“华章计算机”公众号查看。
+关注继续查看

3.2 TCP头部结构

TCP头部信息出现在每个TCP报文段中,用于指定通信的源端端口,目的端端口,管理TCP连接等,本节详细介绍TCP的头部结构,包括固定头部结构和头部选项。

3.2.1 TCP固定头部结构

TCP头部结构如图3-3所示,其中的诸多字段为管理TCP连接和控制数据流提供了足够的信息。

image

16位端口号(port number):告知主机该报文段是来自哪里(源端口)以及传给哪个上层协议或应用程序(目的端口)的。进行TCP通信时,客户端通常使用系统自动选择的临时端口号,而服务器则使用知名服务端口号。1.3节中提到过,所有知名服务使用的端口号都定义在/etc/services文件中。

32位序号(sequence number):一次TCP通信(从TCP连接建立到断开)过程中某一个传输方向上的字节流的每个字节的编号。假设主机A和主机B进行TCP通信,A发送给B的第一个TCP报文段中,序号值被系统初始化为某个随机值ISN(Initial Sequence 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位标志位包含如下几项:

image

16位窗口大小(window size):是TCP流量控制的一个手段。这里说的窗口,指的是接收通告窗口(Receiver Window,RWND)。它告诉对方本端的TCP接收缓冲区还能容纳多少字节的数据,这样对方就可以控制发送数据的速度。

16位校验和(TCP checksum):由发送端填充,接收端对TCP报文段执行CRC算法以检验TCP报文段在传输过程中是否损坏。注意,这个校验不仅包括TCP头部,也包括数据部分。这也是TCP可靠传输的一个重要保障。

16位紧急指针(urgent pointer):是一个正的偏移量。它和序号字段的值相加表示最后一个紧急数据的下一字节的序号。因此,确切地说,这个字段是紧急指针相对当前序号的偏移,不妨称之为紧急偏移。TCP的紧急指针是发送端向接收端发送紧急数据的方法。我们将在后面讨论TCP紧急数据。

3.2.2 TCP头部选项

TCP头部的最后一个选项字段(options)是可变长的可选信息。这部分最多包含40字节,因为TCP头部最长是60字节(其中还包含前面讨论的20字节的固定部分)。典型的TCP头部选项结构如图3-4所示。

image

选项的第一个字段kind说明选项的类型。有的TCP选项没有后面两个字段,仅包含1字节的kind字段。第二个字段length(如果有的话)指定该选项的总长度,该长度包括kind字段和length字段占据的2字节。第三个字段info(如果有的话)是选项的具体信息。常见的TCP选项有7种,如图3-5所示。

image

kind=0是选项表结束选项。

kind=1是空操作(nop)选项,没有特殊含义,一般用于将TCP选项的总长度填充为4字节的整数倍。

kind=2是最大报文段长度选项。TCP连接初始化时,通信双方使用该选项来协商最大报文段长度(Max Segment Size,MSS)。TCP模块通常将MSS设置为(MTU-40)字节(减掉的这40字节包括20字节的TCP头部和20字节的IP头部)。这样携带TCP报文段的IP数据报的长度就不会超过MTU(假设TCP头部和IP头部都不包含选项字段,并且这也是一般情况),从而避免本机发生IP分片。对以太网而言,MSS值是1460(1500-40)字节。

kind=3是窗口扩大因子选项。TCP连接初始化时,通信双方使用该选项来协商接收通告窗口的扩大因子。在TCP的头部中,接收通告窗口大小是用16位表示的,故最大为65?535字节,但实际上TCP模块允许的接收通告窗口大小远不止这个数(为了提高TCP通信的吞吐量)。窗口扩大因子解决了这个问题。假设TCP头部中的接收通告窗口大小是N,窗口扩大因子(移位数)是M,那么TCP报文段的实际接收通告窗口大小是N乘2M,或者说N左移M位。注意,M的取值范围是0~14。我们可以通过修改/proc/sys/net/ipv4/tcp_window_scaling内核变量来启用或关闭窗口扩大因子选项。

和MSS选项一样,窗口扩大因子选项只能出现在同步报文段中,否则将被忽略。但同步报文段本身不执行窗口扩大操作,即同步报文段头部的接收通告窗口大小就是该TCP报文段的实际接收通告窗口大小。当连接建立好之后,每个数据传输方向的窗口扩大因子就固定不变了。关于窗口扩大因子选项的细节,可参考标准文档RFC 1323。

kind=4是选择性确认(Selective Acknowledgment,SACK)选项。TCP通信时,如果某个TCP报文段丢失,则TCP模块会重传最后被确认的TCP报文段后续的所有报文段,这样原先已经正确传输的TCP报文段也可能重复发送,从而降低了TCP性能。SACK技术正是为改善这种情况而产生的,它使TCP模块只重新发送丢失的TCP报文段,不用发送所有未被确认的TCP报文段。选择性确认选项用在连接初始化时,表示是否支持SACK技术。我们可以通过修改/proc/sys/net/ipv4/tcp_sack内核变量来启用或关闭选择性确认选项。

kind=5是SACK实际工作的选项。该选项的参数告诉发送方本端已经收到并缓存的不连续的数据块,从而让发送端可以据此检查并重发丢失的数据块。每个块边沿(edge of block)参数包含一个4字节的序号。其中块左边沿表示不连续块的第一个数据的序号,而块右边沿则表示不连续块的最后一个数据的序号的下一个序号。这样一对参数(块左边沿和块右边沿)之间的数据是没有收到的。因为一个块信息占用8字节,所以TCP头部选项中实际上最多可以包含4个这样的不连续数据块(考虑选项类型和长度占用的2字节)。

kind=8是时间戳选项。该选项提供了较为准确的计算通信双方之间的回路时间(Round Trip Time,RTT)的方法,从而为TCP流量控制提供重要信息。我们可以通过修改/proc/sys/net/ipv4/tcp_timestamps内核变量来启用或关闭时间戳选项。

3.2.3 使用tcpdump观察TCP头部信息

在2.3节中,我们利用tcpdump抓取了一个数据包并分析了其中的IP头部信息,本节分析其中与TCP协议相关的部分(后面的分析中,我们将所有tcpdump抓取到的数据包都称为TCP报文段,因为TCP报文段既是数据包的主要内容,也是我们主要讨论的对象)。为了方便阅读,先将该TCP报文段的内容复制于代码清单3-1中。

image

tcpdump输出Flags[S],表示该TCP报文段包含SYN标志,因此它是一个同步报文段。如果TCP报文段包含其他标志,则tcpdump也会将该标志的首字母显示在“Flags”后的方括号中。

seq是序号值。因为该同步报文段是从127.0.0.1.41621(客户端IP地址和端口号)到127.0.0.1.23(服务器IP地址和端口号)这个传输方向上的第一个TCP报文段,所以这个序号值也就是此次通信过程中该传输方向的ISN值。并且,因为这是整个通信过程中的第一个TCP报文段,所以它没有针对对方发送来的TCP报文段的确认值(尚未收到任何对方发送来的TCP报文段)。
win是接收通告窗口的大小。因为这是一个同步报文段,所以win值反映的是实际的接收通告窗口大小。

options是TCP选项,其具体内容列在方括号中。mss是发送端(客户端)通告的最大报文段长度。通过ifconfig命令查看回路接口的MTU为16436字节,因此可以预想到TCP报文段的MSS为16396(16436-40)字节。sackOK表示发送端支持并同意使用SACK选项。TS val是发送端的时间戳。ecr是时间戳回显应答。因为这是一次TCP通信的第一个TCP报文段,所以它针对对方的时间戳的应答为0(尚未收到对方的时间戳)。紧接着的nop是一个空操作选项。wscale指出发送端使用的窗口扩大因子为6。

接下来我们分析tcpdump输出的字节码中TCP头部对应的信息,它从第21字节开始,如表3-1所示。

image

从表3-1中可见,TCP报文段头部的二进制码和tcpdump输出的TCP报文段描述信息完全对应。在后面的tcpdump输出中,我们将省略大部分TCP头部信息,仅显示序号、确认号、窗口大小以及标志位等与主题相关的字段。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
《高性能Linux服务器构建实战》——1.9节本章小结
本节书摘来自华章社区《高性能Linux服务器构建实战》一书中的第1章,第1.9节本章小结,作者:高俊峰,更多章节内容可以访问云栖社区“华章社区”公众号查看
982 0
《高性能Linux服务器构建实战》——1.8节实战Nginx与Perl、Java的安装与配置
本节书摘来自华章社区《高性能Linux服务器构建实战》一书中的第1章,第1.8节实战Nginx与Perl、Java的安装与配置,作者:高俊峰,更多章节内容可以访问云栖社区“华章社区”公众号查看
1230 0
《高性能Linux服务器构建实战》——1.5节Nginx常用配置实例
本节书摘来自华章社区《高性能Linux服务器构建实战》一书中的第1章,第1.5节Nginx常用配置实例,作者:高俊峰,更多章节内容可以访问云栖社区“华章社区”公众号查看
1093 0
《高性能Linux服务器构建实战》——1.4节Nginx的安装与配置
本节书摘来自华章社区《高性能Linux服务器构建实战》一书中的第1章,第1.4节Nginx的安装与配置,作者:高俊峰,更多章节内容可以访问云栖社区“华章社区”公众号查看
1758 0
服务器性能配置要点总结
(1).操作系统 当前主流的服务器操作系统则主要分为:Windows server、UNIX、Linux、NetWare这四大阵容。不同的系统有不同的特点,要根据情况来判断Windows server是用户群体最大的服务器系统,不得不多做介绍。
1194 0
Linux性能测试 tcpdump命令
用简单的话来定义tcpdump,就是:dump the traffic on a network,根据使用者的定义对网络上的数据包进行截获的包分析工具。 tcpdump可以将网络中传送的数据包的“头”完全截获下来提供分析。
1202 0
开启irqbalance提升服务器性能
操作系统 性能调休   公司有次压测存在一个问题:CPU资源压不上去,一直在40%已达到了性能瓶颈,后定位到原因,所在的服务器在压测过程中产生的中断都落在CPU0上处理,这种中断并没有均衡到各个CPU,导致单个CPU过载而形成瓶颈。
5857 0
就是要你懂 TCP-- 最经典的TCP性能问题
# 就是要你懂 TCP-- 最经典的TCP性能问题 ### 问题描述 某个PHP服务通过Nginx将后面的tair封装了一下,让其他应用可以通过http协议访问Nginx来get、set 操作tair 上线后测试一切正常,每次操作几毫秒,但是有一次有个应用的value是300K,这个时候set一次需要300毫秒以上。 在没有任何并发压力单线程单次操作也需要这么久,这个延迟是没有道
3465 0
10059
文章
0
问答
来源圈子
更多
+ 订阅
文章排行榜
最热
最新
相关电子书
更多
JS零基础入门教程(上册)
立即下载
性能优化方法论
立即下载
手把手学习日志服务SLS,云启实验室实战指南
立即下载