来来来, 爷们. 不是一直说纸上得来终觉浅么. 今咱就抓个数据报具体看一看真实网络中的 IP 报首部.
操作方法很简单, 使用wireshark
进行抓包. 抓包后随便找个包看一下就行, 毕竟所有通信的包都需要经过网络层.(同时, wireshark
会对协议的相关信息给出标识, 更方便我们查看)
其中数据链路层的首部信息在整个数据的最前面, 其后跟着的是网络层, 传输层, 最后剩下的是传输的数据内容. 这个很好理解, 数据从上到下, 每过一层, 都会添加对应的头部信息, 先过传输层就先加上咯.
咱们今儿个主要就看看 IP 协议的首部内容. 走着…
要查看指定字段在其中的位置, 左键点击一下, 数据内容就会高亮了. 好贴心哦.
简单介绍一下各个字段的意思:
- 协议版本号(4b): 标识当前 IP 协议的版本号.
- 首部长度(4b): 标识首部长度. 单位是/4B. 也就是首部最长15*4=60B
- 区分服务(8b):
- 总长度(16b): 首部+数据的长度. 因为 TCP 的首部是在传输层加上的, 所以传输层的首部也会被认为是数据的一部分. IP 层可传输的数据长度为 65535-60=65475B. 不过一般碍于各设备 MTU 的不同, 都会被分段传输
- 标识(16b): 当数据包被分组时, 用于标识不同的分组. 方便接收方对数据包进行重组
- 标志(3b): 用于一些特殊标志
- 片偏移量(13b): 当数据包超出长度后, 会分组传输. 此字段标识数据的偏移量. 单位是/8B
- 生存时间(8b): 数据包在网络中的寿命, 经过 n 跳之后就不再转发了
- 协议(8b): 标识当前包的数据部分协议
- 校验和(8b): 用于校验在网络传输中是否失真. 仅校验首部
- 源地址(32b): 数据包的源IP地址
- 目标地址(32b): 数据包的目标 IP 地址
- 可选内容: 一些其他的可选字段
对于网络层协议来说, 每增加一个字段, 都会影响整体的传输速度. 所以当初设计协议的时候, 定是经过了一再斟酌, 最终才保留了这些不可获取的字段.
协议版本号
标识当前协议的版本, 目前主要用来区分 IPV4和 IPV6.
若此字段缺失, 则无法区分不同版本 IP 协议
首部长度
因为协议的首部存在可选字段, 所以需要添加字段用来指明首部的长度. 以4B 为一个单位应该也是经过多次探讨的了. 当首部为20b 时, 则没有使用可选字段.
若此字段缺失, 无法正确识别协议首部结尾.
区分服务
标识此数据包在传输过程中的一些要求服务.
- 1-3位: 标识数据包重要性. 在网络分组传输种, 较为重要的包会优先传输. 如一个语音通话的数据包, 和一个文件下载的数据包, 明显前者更为优先.
- 4位: 0(正常延迟), 1(想要较低的延迟)
- 5位: 1(想要高流量)
- 6位: 1(要高可靠性)
- 7位: 也是拥塞控制相关的.
- 8位: 1(网络拥塞预警)
总长度
用于对识别当前数据报的结尾.
标识
因为数据在网络层会被分片, 所以增加标识分片所在分组.
若此字段缺失, 则无法对数据包进行正确重组.
标志
- 第一位: 保留
- 第二位: 0(可以分段), 1(不能分段)
- 第三位: 0(当前是最后一个分段), 1(后面还有更多的分段)
偏移量
当接收方接收到多个数据分段时, 进行重组的依据. 该字段占13b, 单位是8B. 也就是说 IP 协议传输数据超过: (2^14-1)*8=131064B≈123kb. 不过一个网络层的包也不会这么大.
而网络层对数据包进行分段是依据 MTU 计算的. MTU 则是其自动协商, 取链路最小值.
若此字段缺失, 则接收方无法对数据包进行正确重组.
生存时间
就是你在使用ping
命令时, 显示的ttl
. 此值每经过一次转发, 就会减一. 当减到0的时候, 该数据包就被丢弃了.
若此字段缺失, 当出现在网络中不存在的目标, 导致数据包在网络中循环传输时永远都不会消失. 而这样的数据一多, 则整个网络都会变得拥堵.
协议
标明数据部分的协议, 用于正确识别数据包上层协议, 并将数据正确转交给指定进程.
搜一下: IP 协议号, 随便打开一个可以看到所有的协议.
若此字段缺失, 则网络层无法将数据正确上交.
校验和
接收方校验在物理传输过程中, 协议首部是否存在损坏. 数据部分不做检查.
若此字段缺失, 则接收方无法缺失接收的数据与发送的数据是否一致.
源地址
用于标识数据包的源地址.
目标地址
用于标识数据包的目标地址.
可选内容
方便后面对协议的扩充. 现在已有的如:
- 记录路径: 每个路由器都记下其IP 地址
- 记录时间戳: 每个路由都记下其IP 与时间
- 等等
感觉可选内容在使用中很少用到, 我抓了各种包, 暂时还没有碰到过有使用的.
协议在设计的时候真的是省吃俭用啊, 平常开发时用到的数据都是以字节为单位的, 人家网络层协议是以位为单位使用的.
后面再看TCP
首部的时候, 也可以如此查看其在传输过程种的真正模样.
爷们, 希望你看到这里了…