Fork me on GitHub

IP协议详解

众所周知,IP是TCP/IP协议族中最为核心的协议,深入了解IP协议对我们实际开发、网络编程据有很大的帮助,遇到问题时,能知其然知其所以然,调试问题时能快速定位问题源并加以解决。

 每次写socket编程时,遇到网络错误或者底层错误时,都是知其然不知其所以然,对于我这种喜欢捣鼓底层,喜欢明白事物本身实质的,显然是不行的,遂拿起了《TCP/IP详解》这三件套,书的作者W. Richard Stevens是位很牛逼的大佬,国际知名的Unix和网络专家前贝尔实验室Unix系统V版本4的开发人员之一,除了TCP/IP三卷(协议、实现、TCP事务协议),还著有有着Unix圣经之称的《Unix网络编程》(两卷本),有兴趣的小伙伴都可以去看看。

此篇文章是针对书中第三章作的一份小结

IP:网际协议

 IP是TCP/IP协议族的核心,它位于TCP/IP四层模型的网络层,负责Internet网络之间的通信,并定义了数据传输时的基本单元和格式,还定义了数据包的递交方法和路由选择。
  1.IP是面向无连接的传输服务,不维护IP数据报发送后的状态信息,数据报在传输过程可能丢失,统一交给上层自己去维护
  2.IP是不可靠的数据投递服务,IP协议本身没有办法确认发送的报文是否被正确接受,数据报可能在线路延迟、路由错误、分片、重组等过程中损坏,IP不检测这些错误,也没有可靠的机制来通知发送方或接收方

1. IP地址

 IP地址是一个32位的二进制地址,由网络号和主机号组成。为了方便记忆,将它们分为4组,每组8位由小数点分开,这种表示方法叫做点分十进制,例如192.168.1.1。

1.1 IP地址类别

 IP地址分为五类,A类,B类,C类,D类,E类

类别 网段 区分 地址范围 网络数 主机数
A类 0-127 首位为0 1.0.0.1~127.255.255.254 126(2^7-2) 2^24-2
B类 128-191 首位为10 128.0.0.1~191.255.255.254 16383(2^14-1) 2^16-2
C类 192-223 首位为110 192.0.0.1~223.255.255.254 2^24-1 2^8-2
D类 224-239 首位为1110 224.0.0.1~239.255.255.254 不区分网络地址和主机地址
E类 240~255 首位为11110 保留地址
  • A类:由一个字节的网络号和三个字节的主机号组成,默认子网掩码(255.0.0.0),最高位必须为0,网络数减2是因为
    • 1.网络号全为0的IP地址为保留地址,表示本网络
    • 2.A类IP地址中网络号为127的地址保留用于环回测试本机的进程间通信(127.0.0.0~127.255.255.255都为保留地址)
  • B类:由两个字节的网络号和两个字节的主机号组成,默认子网掩码(255.255.0.0),网络数减1也是因为网络全为0表示本网络,不能被指派,前面首位为0。
  • C类:由三个字节的网络号和两个字节的主机号组成,默认子网掩码(255.255.255.0),减1同理
  • D类:保留地址,不分网络和主机地址,主要用于多播地址
  • E类:保留地址,为将来使用保留
1.2 公有地址和私有地址

 我们能经常听到公有地址和私有地址,包括去腾讯云、阿里云购买服务器,都会分配一个公有地址和一个私有地址

公有地址:公有地址(Public address)由Inter NIC(Internet Network Information Center 因特网信息中心)负责。这些IP地址分配给注册并向Inter NIC提出申请的组织机构。通过它直接访问因特网。简单一句话讲就是外部主机能访问你这个地址的就是公有地址
私有地址:私有地址属于非注册地址,专门为组织机构内部使用,只能处于在同一网段的主机才能访问,属于局域网范畴

1.3 私有地址范围

 以下为A、B、C三类私有地址范围,只用于在局域网上
| 类别 | 范围 |
| —- | —- |
|A类|10.0.0.0~10.255.255.255|
|B类|172.16.0.0~172.31.255.255|
|C类|192.168.0.0~192.168.255.255|

2.IP首部

 当应用程序传送数据时,数据被送入协议栈中,经过TCP/IP四层模型时,其中每一层对收到的数据都要增加一些首部信息(有时候还会增加尾部信息),IP传给数据链路层的数据单元称作IP数据报(IP datagram).

从左到右,依次是最高位到最低位。
大端字节序(big endian):高位字节在前,低位字节在后。也就是0~7bit在前,其次8~15bit…
小端字节序(little endian):低位字节在前,高位字节在后。24~31bit在前,依次

2.1 字段含义
  • 版本:占4位,表示IP协议的版本,目前是4,因此也叫做IPv4。IPv6目前还没普及。
  • 首部长度:4位,指IP首部大小,单位字节。因为该字段值最大为15,所以IP首部最大长度为60个字节,且IP首部长度必须为4的整数倍,不是整数倍使用最后的选项字段进行填充
  • 服务类型(TOS):8位,用来获取更好的服务,但实际上一直没被使用过
    • 前3bit表示优先权(现已被忽略)
    • 4bit的TOS字段包括最小时延、最大吞吐量、最高可靠性、最小费用
    • 1bit未用位必须置0
  • 总长度:16位,指整个IP数据报的长度,以字节为单位,利用IP首部长度字段和该字段就可以知道IP数据报中数据内容的起始位置和长度,由于该字段长16bit,所以IP数据报最长可达65535字节(最大传送单元MTU),但要注意当一个IP数据报经过链路层被封装帧时,一定不能超过数据链路层的MTU值
  • 标识:16位,唯一地标示主机发送的每一份数据报,通常每发送一份报文它的值就会加1,主要用于分片重组时,通过该字段重组为原来的数据报
  • 标志:占3位
    • 标志字段中的最低位记为MF(More Fragment)。MF=1即表示后面“还有分片”的数据报。MF=0表示这已是若干数据报片中的最后一个
    • 标志字段中间的一位记为DF(Don’t Fragment),意思是“不能分片”。只有当DF=0时才允许分片。
  • 片偏移:13位,在分片后,某片在原分组中的相对位置。也就是说,相对用户数据字段的起点,该片从何处开始。片偏移以8个字节为偏移单位。这就是说,每个分片的长度一定是8字节(64位)的整数倍。
  • TTL:8位,单位秒或跳站数目,表示数据报可以经过的最多路由器数,初始值由源主机设置,一旦经过一个处理它的路由器值就减1,当值为0时,数据报就被丢弃,并发送ICMP报文通知源主机
  • 协议:8位,指数据报传输数据是用的哪种协议,在linux系统的/etc/protocols文件中定义了所有上层协议对应的值,ICMP为1,TCP为6,UDP是17
  • 首部校验和:16位,指根据IP首部计算检验和码,用来检查数据报在传输过程中是否出现错误

3.IP路由选择

 IP路由选择是逐跳地(hop-by-hop)进行的,如果目的主机与源主机不是在同一个网络,主机会把数据报发往路由器上,由路由器来转发数据报,直至目的主机。
 路由表中的每一项都包含下面这些信息:

  • 目的IP地址,可以是一个完整的主机地址,也可以是一个网络地址。由标志字段指定
  • 下一跳路由器的IP地址,或者有直接相连的网络IP地址,下一跳路由器不是最终目的,但是通过它可以将数据报转发到最终目的
  • 标志:指明目的IP地址是网络地址还是主机地址,另一个标志指明下一跳路由器是否为真正的路由器,还是一个直连的接口
  • 为数据报的传输指定一个网络接口

从中我们可以看出,IP并不知道任何目的地完整路径,所以IP路由选择主要完成以下功能:

  1. 搜索路由表,寻找能与目的IP地址完全匹配的表目。找到,则把报文发送给该表目指定的下一跳路由器或者直连的网络接口(取决于标志字段的值)
  2. 搜索路由表,寻找能与目的网络号相匹配的表目。找到,则把报文发送给表目指定的下一跳路由器或直连的网络接口。目的网络上所有主机都可以通过这个表目来处置。这种搜索方法必须考虑子网掩码
  3. 搜索路由表,寻找标为默认的表目。找到,则把报文发送该表目指定的下一跳路由器。

假如上面这些步骤都没有成功,那么这个数据报就不能被传送,且就会返回主机不可达或者网络不可达

4.子网掩码

 子网掩码是32位的二进制数,表示地址哪一部分为网络地址,哪一部分为主机地址。对应网络地址的位都是1,主机地址都为0。
 例如,有一个IP地址是:192.168.0.5,默认子网掩码是:255.255.255.0,那么该IP的网络地址是192.168.0.0
 计算方法:
1. 将IP地址与子网掩码转换成二进制
2. 将转换成二进制的IP地址和子网掩码做与运算,得到的结果就是网络地址
3. 将二进制形式的子网掩码取反
4. 将取反后的子网掩码和IP地址做与运算,得到的结果就是主机地址

您的赞赏是对我最大的支持,谢谢!