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

2.2 IPv4头部结构

2.2.1 IPv4头部结构

IPv4的头部结构如图2-1所示。其长度通常为20字节,除非含有可变长的选项部分。

4位版本号(version)指定IP协议的版本。对IPv4来说,其值是4。其他IPv4协议的扩展版本(如SIP协议和PIP协议),则具有不同的版本号(它们的头部结构也和图2-1不同)。

4位头部长度(header length)标识该IP头部有多少个32?bit字(4字节)。因为4位最大能表示15,所以IP头部最长是60字节。

8位服务类型(Type Of Service,TOS)包括一个3位的优先权字段(现在已经被忽略),4位的TOS字段和1位保留字段(必须置0)。4位的TOS字段分别表示:最小延时,最大吞吐量,最高可靠性和最小费用。其中最多有一个能置为1,应用程序应该根据实际需要来设置它。比如像ssh和telnet这样的登录程序需要的是最小延时的服务,而文件传输程序ftp则需要最大吞吐量的服务。

16位总长度(total length)是指整个IP数据报的长度,以字节为单位,因此IP数据报的最大长度为65?535(216-1)字节。但由于MTU的限制,长度超过MTU的数据报都将被分片传输,所以实际传输的IP数据报(或分片)的长度都远远没有达到最大值。接下来的3个字段则描述了如何实现分片。

16位标识(identification)唯一地标识主机发送的每一个数据报。其初始值由系统随机生成;每发送一个数据报,其值就加1。该值在数据报分片时被复制到每个分片中,因此同一个数据报的所有分片都具有相同的标识值。

3位标志字段的第一位保留。第二位(Don’t Fragment,DF)表示“禁止分片”。如果设置了这个位,IP模块将不对数据报进行分片。在这种情况下,如果IP数据报长度超过MTU的话,IP模块将丢弃该数据报并返回一个ICMP差错报文。第三位(More Fragment,MF)表示“更多分片”。除了数据报的最后一个分片外,其他分片都要把它置1。

13位分片偏移(fragmentation offset)是分片相对原始IP数据报开始处(仅指数据部分)的偏移。实际的偏移值是该值左移3位(乘8)后得到的。由于这个原因,除了最后一个IP分片外,每个IP分片的数据部分的长度必须是8的整数倍(这样才能保证后面的IP分片拥有一个合适的偏移值)。

8位生存时间(Time To Live,TTL)是数据报到达目的地之前允许经过的路由器跳数。TTL值被发送端设置(常见的值是64)。数据报在转发过程中每经过一个路由,该值就被路由器减1。当TTL值减为0时,路由器将丢弃数据报,并向源端发送一个ICMP差错报文。TTL值可以防止数据报陷入路由循环。

8位协议(protocol)用来区分上层协议,我们在第1章讨论过。/etc/protocols文件定义了所有上层协议对应的protocol字段的数值。其中,ICMP是1,TCP是6,UDP是17。/etc/protocols文件是RFC 1700的一个子集。

16位头部校验和(header checksum)由发送端填充,接收端对其使用CRC算法以检验IP数据报头部(注意,仅检验头部)在传输过程中是否损坏。

32位的源端IP地址和目的端IP地址用来标识数据报的发送端和接收端。一般情况下,这两个地址在整个数据报的传递过程中保持不变,而不论它中间经过多少个中转路由器。关于这一点,我们将在第4章进一步讨论。

IPv4最后一个选项字段(option)是可变长的可选信息。这部分最多包含40字节,因为IP头部最长是60字节(其中还包含前面讨论的20字节的固定部分)。可用的IP选项包括:


关于IP头部选项字段更详细的信息,请参考IP协议的标准文档RFC 791。不过这些选项字段很少被使用,使用松散源路由选择和严格源路由选择选项的例子大概仅有traceroute程序。此外,作为记录路由IP选项的替代品,traceroute程序使用UDP报文和ICMP报文实现了更可靠的记录路由功能,详情请参考文档RFC 1393。

2.2.2 使用tcpdump观察IPv4头部结构

为了深入理解IPv4头部中每个字段的含义,我们从测试机器ernest-laptop上执行telnet命令登录本机,并用tcpdump抓取这个过程中telnet客户端程序和telnet服务器程序之间交换的数据包。具体的操作过程如下:

$ sudo tcpdump -ntx -i lo           #抓取本地回路上的数据包
$ telnet 127.0.0.1          #开启另一个终端执行telnet命令登录本机
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
Ubuntu 9.10
ernest-laptop login: ernest     #输入用户名并回车
Password:                   #输入密码并回车

此时观察tcpdump输出的第一个数据包,其内容如代码清单2-1所示。

该数据包描述的是一个IP数据报。由于我们是使用telnet登录本机的,所以IP数据报的源端IP地址和目的端IP地址都是“127.0.0.1”。telnet服务器程序使用的端口号是23(参见/etc/services文件),而telnet客户端程序使用临时端口号41621与服务器通信。关于临时端口号,我们将在第3章讨论。“Flags”、“seq”、“win”和“options”描述的都是TCP头部信息,这也将在第3章讨论。“length”指出该IP数据报所携带的应用程序数据的长度。

这次抓包我们开启了tcpdump的-x选项,使之输出数据包的二进制码。此数据包共包含60字节,其中前20字节是IP头部,后40字节是TCP头部,不包含应用程序数据(length值为0)。现在我们分析IP头部的每个字节,如表2-1所示。

由表2-1可见,telnet服务选择使用具有最小延时的服务,并且默认使用的传输层协议是TCP协议(回顾第1章讨论的分用)。这些都符合我们通常的理解。这个IP数据报没有被分片,因为它没有携带任何应用程序数据。接下来我们将抓取并讨论被分片的IP数据报。

时间: 2024-09-19 10:08:48

《Linux高性能服务器编程》——2.2 IPv4头部结构的相关文章

《Linux高性能服务器编程》——导读

前 言 为什么要写这本书 目前国内计算机书籍的一个明显弊病就是内容宽泛而空洞.很多书籍长篇大论,恨不得囊括所有最新的技术,但连一个最基本的技术细节也无法解释清楚.有些书籍给读者展现的是网络上随处可见的知识,基本没有自己的观点,甚至连一点自己的总结都没有.反观大师们的经典书籍,整本书只专注于一个问题,而且对每个技术细节的描述都是精雕细琢.最关键的是,我们在阅读这些经典书籍时,似乎是在用心与一位编程高手交流,这绝对是一种享受. 我们把问题缩小到计算机网络编程领域.关于计算机网络编程的相关书籍,不得不

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

3.2 TCP头部结构 TCP头部信息出现在每个TCP报文段中,用于指定通信的源端端口,目的端端口,管理TCP连接等,本节详细介绍TCP的头部结构,包括固定头部结构和头部选项. 3.2.1 TCP固定头部结构 TCP头部结构如图3-3所示,其中的诸多字段为管理TCP连接和控制数据流提供了足够的信息. 16位端口号(port number):告知主机该报文段是来自哪里(源端口)以及传给哪个上层协议或应用程序(目的端口)的.进行TCP通信时,客户端通常使用系统自动选择的临时端口号,而服务器则使用知名

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

2.7 IPv6头部结构 IPv6协议是网络层技术发展的必然趋势.它不仅解决了IPv4地址不够用的问题,还做了很大的改进.比如,增加了多播和流的功能,为网络上多媒体内容的质量提供精细的控制:引入自动配置功能,使得局域网管理更方便:增加了专门的网络安全功能等.本节简要地讨论IPv6头部结构,它的更多细节请参考其标准文档RFC 2460. 2.7.1 IPv6固定头部结构 IPv6头部由40字节的固定头部和可变长的扩展头部组成.图2-6所示是IPv6的固定头部结构. 4位版本号(version)指定

《Linux高性能服务器编程》——3.3 TCP连接的建立和关闭

3.3 TCP连接的建立和关闭 本节我们讨论建立和关闭TCP连接的过程. 3.3.1 使用tcpdump观察TCP连接的建立和关闭 首先从ernest-laptop上执行telnet命令登录Kongming20的80端口,然后抓取这一过程中客户端和服务器交换的TCP报文段.具体操作过程如下: $ sudo tcpdump -i eth0 –nt '(src 192.168.1.109 and dst 192.168.1.108) or (src 192.168.1.108 and dst 192

《Linux高性能服务器编程》——1.6 DNS工作原理

1.6 DNS工作原理 我们通常使用机器的域名来访问这台机器,而不直接使用其IP地址,比如访问因特网上的各种网站.那么如何将机器的域名转换成IP地址呢?这就需要使用域名查询服务.域名查询服务有很多种实现方式,比如NIS(Network Information Service,网络信息服务).DNS和本地静态文件等.本节主要讨论DNS. 1.6.1 DNS查询和应答报文详解 DNS是一套分布式的域名服务系统.每个DNS服务器上都存放着大量的机器名和IP地址的映射,并且是动态更新的.众多网络客户端程

《Linux高性能服务器编程》——第2章 IP协议详解 2.1 IP服务的特点

第2章 IP协议详解 IP协议是TCP/IP协议族的核心协议,也是socket网络编程的基础之一.本章从两个方面较为深入地探讨IP协议: 由于32位表示的IP地址即将全部使用完,因此人们开发出了新版本的IP协议,称为IPv6协议,而原来的版本则称为IPv4协议.本章前面部分的讨论都是基于IPv4协议的,只在最后一节简要讨论IPv6协议. 在开始讨论前,我们先简单介绍一下IP服务. 2.1 IP服务的特点 IP协议是TCP/IP协议族的动力,它为上层协议提供无状态.无连接.不可靠的服务. 无状态(

《Linux高性能服务器编程》——3.9 TCP超时重传

3.9 TCP超时重传 在3.6节-3.8节中,我们讲述了TCP在正常网络情况下的数据流.从本节开始,我们讨论异常网络状况下(开始出现超时或丢包),TCP如何控制数据传输以保证其承诺的可靠服务. TCP服务必须能够重传超时时间内未收到确认的TCP报文段.为此,TCP模块为每个TCP报文段都维护一个重传定时器,该定时器在TCP报文段第一次被发送时启动.如果超时时间内未收到接收方的应答,TCP模块将重传TCP报文段并重置定时器.至于下次重传的超时时间如何选择,以及最多执行多少次重传,就是TCP的重传

《Linux高性能服务器编程》——第1章 TCP/IP协议族 1.1 TCP/IP协议族体系结构以及主要协议

第1章 TCP/IP协议族 现在Internet(因特网)使用的主流协议族是TCP/IP协议族,它是一个分层.多协议的通信体系.本章简要讨论TCP/IP协议族各层包含的主要协议,以及它们之间是如何协作完成网络通信的. TCP/IP协议族包含众多协议,我们无法一一讨论.本书将在后续章节详细讨论IP协议和TCP协议,因为它们对编写网络应用程序具有最直接的影响.本章则简单介绍其中几个相关协议:ICMP协议.ARP协议和DNS协议,学习它们对于理解网络通信很有帮助.读者如果想要系统地学习网络协议,那么R

《Linux高性能服务器编程》——3.4 TCP状态转移

3.4 TCP状态转移 TCP连接的任意一端在任一时刻都处于某种状态,当前状态可以通过netstat命令(见第17章)查看.本节我们要讨论的是TCP连接从建立到关闭的整个过程中通信两端状态的变化.图3-8是完整的状态转移图,它描绘了所有的TCP状态以及可能的状态转换. 图3-8中的粗虚线表示典型的服务器端连接的状态转移:粗实线表示典型的客户端连接的状态转移.CLOSED是一个假想的起始点,并不是一个实际的状态. 3.4.1 TCP状态转移总图 我们先讨论服务器的典型状态转移过程,此时我们说的连接