数据包封装
传输层及其以下的机制由 内核提供,应用层由 用户进程提供(后面将介绍如何使用socket API编写应用程序),应用程序 对通讯数据的含义进行解释,而传输层及其以下处理通讯的细节,将数据从一台计算机通过一定的路径发送到另一台计算机。应用层数据通过协议栈发到网络上时,每层协议都要加上一个数据首部(header),称为封装(Encapsulation),如下图所示:
TCP/IP通信过程:
TCP/TP数据包封装:
不同的协议层 对数据包有不同的名称:
序号 | 层 | 传输对象 |
---|---|---|
1 | 应用层 | 报文(Message) |
2 | 传输层 | (1)TCP 报文段(Segment) (2)UDP 数据报(Datagram) |
3 | 网络层 | 分组 / 数据包(Packet) |
4 | 网络接口层 | 帧(Frame) |
数据 封装成帧 后发到传输介质上,到达目的主机后每层协议再剥掉相应的首部,最后将应用层数据交给应用程序处理。
1、TCP 报文段(Segment)格式
- 16位源端口号:16-bit source port number
- 16位目标端口号:16-bit destination prot number
- 32位顺序号:32-bit sequence number
- 32位应答号:32-bit acknowledgment number
- 4位头部长度:4-bit header length
- 保留位:reserved(6 bit)
- URG:紧急标志位
- ACK:应答标志位(表明应答号之前的数据接收成功)
- PSH:不进行缓存直接推送到应用的标志位
- RST:标志重连接的标志位
- SYN:同步顺序号以初始化连接的标志位
- FIN:发送数据完毕的标志位(表明不会再发送数据过来)
- 窗口大小(用于控流)(16-bit window size)
- 检验和(检验传输的数据是否正确)(16-bit TCP checksum)
- 当URG标志被设置时有效,传送紧急数据(16-bit urgent pointer)
2、UDP 数据报(Datagram)格式
首部字段 很简单,只有8个字节,由4个字段组成,每个字段的长度都是两个字节。
各字段(Field)意义如下:
序号 | 字段(Field) | 描述 |
---|---|---|
1 | 源端口 | 源端口号。 在需要对方回信时选用。不需要时可用全 0 。 |
2 | 目的端口 | 目的端口号。 这在 终点交付报文 时必须使用。 |
3 | 长度 | UDP用户数据报的长度,其最小值是8(仅有首部) |
4 | 校验和 | 检测UDP用户数据报 在传输中是否有错,有错就丢弃。 |
3、IP 分组(Packet)格式
IP数据报的首部长度和数据长度都是可变长的,但总是4字节的整数倍。
- 4位版本:对于IPv4,4位版本字段是4。
- 4位首部长度 的数值是以4字节为单位的,最小值为5,也就是说首部长度最小是4x5=20字节,也就是不带任何选项的IP首部,4位能表示的最大值是15,也就是说首部长度最大是60字节。
- 8位服务类型:TOS字段有3个位用来指定IP数据报的优先级(目前已经废弃不用),还有4个位表示可选的服务类型(最小延迟、最大吐量、最大可靠性、最小成本),还有一个位总是0。
- 16位总长度 是整个数据报(包括
IP首部
和IP层 Payload
)的字 节数。 - 16位标识:每传一个IP数据报,16位的标识加1,可用于 分片和重新组装 数据报。
- 3位标志 和 13位片偏移 用于 分片。
- 8位生存时间 TTL(Time to live)是这样用的:源主机为数据包设定一个生存时间,比如64,每过一个路由器就把该值减1,如果减到0就表示 路由已经太长了仍然找不到目的主机的网络,就丢弃该包,因此这个生存时间的单位不是秒,而是跳(hop)。
- 8位协议字段 指示上层协议是TCP、UDP、ICMP还是IGMP。
- 16位首部校验和:只校验IP首部,数据的校验由更高层协议负责。
- IPv4的IP地址长度为32位。
- 选项字段 的解释从略。
想一想,前面讲了以太网帧中的最小数据长度为46字节,不足46字节的要用填充字节补上,那么如何界定这46字节里 前多少个字节是IP、ARP或RARP数据报 而后面是填充字节?
4、ARP 数据包 格式
在网络通讯时,源主机 的应用程序 知道 目的主机 的IP地址 和端口号,却不知道 目的主机的 硬件地址,而 数据包首先是被 网卡接收 到 再去处理 上层协议的,如果接收到的数据包的硬件地址与本机不符,则直接丢弃。因此在通讯前必须获得 目的主机 的 硬件地址。ARP协议就起到这个作用。
源主机发出 ARP请求,询问“IP地址是192.168.0.1 的主机的 硬件地址 是多少”,并将这个请求广播到本地网段(以太网帧首部的 硬件地址 填 FF:FF:FF:FF:FF:FF 表示 广播),目的主机接收到广播的ARP请求,发现其中的IP地址与本机相符,则发送一个 ARP应答数据包 给源主机,将自己的硬件地址填写在 应答包 中。
每台主机都维护一个ARP缓存表,可以用 arp -a 命令查看。缓存表中的表项有过期时间(一般为20分钟),如果20分钟内没有再次使用某个表项,则该表项失效,下次还要发 ARP请求 来获得目的主机的硬件地址。想一想,为什么表项要有过期时间而不是一直有效?
ARP数据报 的格式如下所示:
- 注意到 6个字节的
源MAC地址
、目的MAC地址
在以太网首部
和ARP请求
中各出现一次,对于链路层为以太网的情况是多余的,但如果链路层是其它类型的网络则有可能是必要的。 - 2个字节 硬件类型:指链路层 网络类型,1为以太网。
- 2个字节 协议类型:指要转换的 地址类型,0x0800为IP地址。
- 后面两个地址长度对于
以太网地址
和IP地址
分别为6和4(字节)。 - 2个字节op字段:op字段为1表示ARP请求,op字段为2表示ARP应答。
5、以太网 帧格式(Frame)
- 6个字节 源地址和 目的地址是指 网卡的硬件地址(也叫MAC地址),长度是48位(6个字节),是在网卡出厂时固化的。用 ifconfig 命令看一下,“HWaddr 00:15:F2:14:9E:3F” 部分就是硬件地址。
- 2个字节协议类型 字段有三种值,分别对应 IP、ARP、RARP。
- 4个字节帧末尾 是CRC校验码。
以太网帧中的 数据长度
规定最小46字节,最大1500字节,ARP 和 RARP 数据包的长度不够46字节,要在后面补填充位。
最大值1500 称为以太网的 最大传输单元(MTU),不同的网络类型有不同的 MTU,如果一个数据包从 以太网 路由到 拨号链路上,数据包长度大于拨号链路的 MTU了,则需要对 数据包进行 分片(fragmentation)。
ifconfig 命令的输出中也有“MTU:1500”。注意,MTU这个概念指 数据帧中 有效载荷的最大长度,不包括 帧首部的长度。