网络层——IP协议

Posted Hero 2021

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络层——IP协议相关的知识,希望对你有一定的参考价值。

网络层

网络层概述

网络层主要考虑数据传输的路上问题,在复杂的网络环境中确定一个合适的路径。
网络层设计要尽量简单,向上层只提供简单灵活的、无连接的、不保证可靠性的数据报服务。网络层不提供服务质量的承诺!

IP 数据报的格式

如何分离与封装?
两个字段:4位首部长度 16位总长度

如何向上交付(分用)?
通过8位协议来做到的,其中填充的是:上层协议是谁,那么是谁填充的呢?对于交付数据来说,那填充者是对端的传输层来填充的。

各个字段的解释

  • 4位版本号:IPV4。

  • 4位首部长度:和TCP报文中的4位首部长度含义相同。单位是4字节,由于IP协议规定了定长的20字节的首部,所以填充的是5,二进制就是0101。

  • 8位服务类型:用来获得更好的服务。
    3位优先权字段(已经弃用),4位TOS字段, 和1位保留字段(必须置为0)。4位TOS分别表示:最小延时、最大吞吐量、最高可靠性、最小成本,这四者相互冲突,只能选择一个。对于ssh/telnet这样的应用程序,最小延时比较重要;对于ftp这样的程序,最大吞吐量比较重要。

  • 16位总长度:首部+数据之和,单位为字节。后文还会详细解释它。

  • 16位标识:IP软件在存储器中维持了一个计数器,没产生一个数据报,计数器就加一,并将此值赋值给标识字段,但是这个“标识”并不是序号,因为IP是无连接服务,数据报不存在按序接收的问题,当数据报长度超过MTU而必须分片时,这个标识字段就被复制到所有的数据报分片的标识字段中。相同的标识字段的值,使得最后能够正确的组装成为原来的数据报。

  • 3位标志字段:
    第一位保留。
    第二位记为DF(Don’t Fragment),意思是不能分片,DF=0时才允许分片。
    第三位记为MF(More Fragment),意思是还有分片,DF=1表示后面还有分片,DF=0表示这已经是若干分片的最后一个了。

  • 13位片偏移:分片相对于原始IP报文开始处的偏移量,其实就是在表示当前分片的有效载荷在原报文中是处于哪个位置。片偏移的单位是8字节,所以片偏移=起始数据/8

  • 8位生存时间:TTL,表明此数据报在网络中的寿命。随着技术的进步,后来把TTL字段的功能改为“跳数限制”。路由器在每次转发 数据报之前就把TTL值减一,若TTL减小到0,就把此数据报丢弃,不在转发。

  • 8位协议:指出此数据报携带的数据是使用何种协议,以便使目的主机的IP层知道应将数据部分上交给哪个协议。

  • 16位头部检验和:使用CRC进行校验,来鉴别头部是否有损坏。

  • 32位源地址:发送端。

  • 32位目的地址:接收端。

  • 选项:我们不关心。

注意:数据报首部中“总长度”字段是指,分片后的每一个分片的首部长度+该分片的数据长度之和。

IP 报文的分片

IP分片不是大多数情况!

为什么会分片?
数据链路层一次可以往网络里发送的数据大小是有限制的 MTU:1500字节
过长的数据报要进行分片处理。

为什么要在网络层里分片?
一旦分片之后,新的报文也要添加新的报头,只有网络层对报头比较了解,数据链路层是不了解的,它也不需要关心,并不是在链路层不能分片,从技术角度也是能做的,但是一旦在链路层分片之后,数据的耦合度就提升了。

谁来组装分片?
对端的网络层IP协议来组装

如何分片?
计算过程:举一个书上的例子,简单易懂
【例4-1】一个数据报的总长度为3820字节,其数据部分为3800字节长(使用固定首部),需要分片为长度不超过1420字节的数据报片。因固定首部长度为20字节,因此每个数据报片的数据部分长度不能超过1400字节。于是分为3个数据报片,其数据部分的长度分别为1400,1400和1000字节。原始数据报首部被复制为各数据报片的首部,但必须修该有关字段的值。

请问这个分片过程传输层知道吗?
不知道,也不需要知道。

分片真的好吗?
分片是有风险的,会提高丢包的风险。所以我们一般不建议分片操作!

如果不想分片,谁说了算?
传输层!链路层规定最多接收1500字节,那么网络层最多就是1480字节,所以传输层和对端的传输层就会协商一次传输的报文字节大小,最大就向下(网络层)交付1480字节,尽量避免分片。

其中一个报文丢失了怎么办?
所以会造成组装失败,所以整个大报文全部丢弃,所以在传输层认为数据丢包了,丢包了就会由发送端重传(这是采用TCP协议的才会重传,采用UDP协议的就是真的丢包了),重复上诉过程。

总结:一般而言,我们还是要减少分片,要求TCP控制自己的单个报文大小!

IP 报文的组装

16位标识是把分片聚合在一起,13位片偏移是把分片重新排列组合在一起。

如何组装?
按照偏移量升序排序。

我怎么知道,有还是没有报文丢失了呢?
我怎么知道,报文收全了呢?
最后一个分片丢失了,是不好判定的。
这时就要用到3位标志位来判断了!

接收端是如何得知,所接受的报文是独立报文还是分片报文呢?
可以采用如下算法:

if(更多分片==1 || 片偏移>0)

	// 分片报文
	set();

else// (更多分片==0 && 片偏移==0)

	// 常规报文

网段划分

IP地址=网络号+主机号

网络号:它标志主机或者路由器所连接的网络,保证互相连接的两个网段具有不同的表示。
主机号:它标志该主机,同一网段内,主机之间具有相同的网络号,但是必须具有不同的主机号。

  • 不同的子网其实就是把网络号相同的主机放到一起。
  • 如果在子网中新增一台主机,则这台主机的网络号和这个子网的网络号一致,但是主机号必须不能和子网中的其他主机重复。

划分问题

通过合理设置主机号和网络号,就可以保证在相互连接的网络中,每台主机的IP地址都不相同。那么问题来了,手动管理子网内的IP,是一个相当麻烦的事情。

  • 有一种技术叫做DHCP, 能够自动的给子网内新增主机节点分配IP地址, 避免了手动管理IP的不便。
  • 一般的路由器都带有DHCP功能. 因此路由器也可以看做一个DHCP服务器。

有类IP地址划分

过去曾经提出一种划分网络号和主机号的方案, 把所有IP 地址分为五类, 如下图所示

  • A类 0.0.0.0到127.255.255.255
  • B类 128.0.0.0到191.255.255.255
  • C类 192.0.0.0到223.255.255.255
  • D类 224.0.0.0到239.255.255.255
  • E类 240.0.0.0到247.255.255.255

随着Internet的飞速发展,这种划分方案的局限性很快显现出来,大多数组织都申请B类网络地址,导致B类地址很快就分配完了,而A类却浪费了大量地址。

例如, 申请了一个B类地址,理论上一个子网内能允许6万5千多个主机。A类地址的子网内的主机数更多.然而实际网络架设中,不会存在一个子网内有这么多的情况. 因此大量的IP地址都被浪费掉了。

无类IP地址划分

针对浪费提出了新的划分方案,称为CIDR(Classless Interdomain Routing)。

  • 引入一个额外的子网掩码(subnet mask)来区分网络号和主机号。
  • 子网掩码也是一个32位的正整数. 通常用一串 "1"表示网络号,"0"表示主机号。
  • 将IP地址和子网掩码进行 “按位与” 操作, 得到的结果就是网络号。
  • 网络号和主机号的划分与这个IP地址是A类、B类还是C类无关。

举个划分子网的例子:

IP地址140.252.20.688C FC 14 44
子网掩码255.255.255.240FF FF FF 00
网络号140.252.20.648C FC 14 40
子网地址范围140.252.20.64~140.252.20.79

特殊的IP

  • 将IP地址中的主机地址全部设为0,就成为了网络号,代表这个局域网。
  • 将IP地址中的主机地址全部设为1, 就成为了广播地址, 用于给同一个链路中相互连接的所有主机发送数据包。
  • 127.*的IP地址用于本机环回(loop back)测试,通常是127.0.0.1。

IP地址数量的限制

 我们知道, IP地址(IPv4)是一个4字节32位的正整数。那么一共只有232个IP地址, 大概是43亿左右。而TCP/IP协议规定,每个主机都需要有一个IP地址。
这意味着,一共只有43亿台主机能接入网络么?
 实际上,由于一些特殊的IP地址的存在,数量远不足43亿。另外IP地址并非是按照主机台数来配置的,而是每一个网卡都需要配置一个或多个IP地址。CIDR在一定程度上缓解了IP地址不够用的问题(提高了利用率,减少了浪费,但是IP地址的绝对上限并没有增加), 仍然不是很够用。

这时候有三种方式来解决:

  • 动态分配IP地址:只给接入网络的设备分配IP地址. 因此同一个MAC地址的设备, 每次接入互联网中, 得到的IP地址不一定是相同的。
  • NAT技术(后面文章重点介绍)。
  • IPv6:IPv6并不是IPv4的简单升级版。这是互不相干的两个协议,彼此并不兼容;IPv6用16字节128位来表示一个IP地址;但是目前IPv6还没有普及;

私有IP和公网IP

首先来查看一下我们电脑上的IP地址:
Windows:

Linux上:

路由器最大的功能是可以用来组建局域网!

如果一个组织内部组建局域网,IP地址只用于局域网内的通信,而不直接连到Internet上,理论上使用任意的IP地址都可以,但是RFC 1918规定了用于组建局域网的私有IP地址

  • 10.*,前8位是网络号,共16,777,216个地址。
  • 172.16.到172.31.前12位是网络号,共1,048,576个地址。
  • 192.168.*前16位是网络号,共65536个地址包含在这个范围中的,都成为私有IP,其余的则称为全局IP(或公网IP)。
  • 一个路由器一般配置两个IP地址:一个WAN口,另一个LAN口,因为要转发报文,所以路由器要横跨两个网络。

我发起请求,在IP报文中填好目的IP和源IP,理论这样发送到了百度服务器,但是百度服务器拿到报文处理后,发现源IP,它无法识别此IP地址,因为允许局域网内私有IP地址重复。所以此时报文是无法直接发送回来的。

此时路由器的作用就出来了,帮你把你报文里的源IP地址替换成为WAN口IP,再转发给下一跳,就如同该报文是由该路由器产生的一般。

总结:我们自己的请求在对外发送的时候,我们的源IP地址可能一直在被中间路由器替换——NAT技术。

报文到达服务器后,如何回来呢?
后面再谈!

路由

基于路由,报文是如何转发的?
IP数据包的传输转发过程也和问路一样:

  • 当IP数据包,到达路由器时,路由器会先查看目的IP。
  • 路由器决定这个数据包是能直接发送给目标主机,还是需要发送给下一个路由器。
  • 依次反复,一直到达目标IP地址。

那么如何判定当前这个数据包该发送到哪里呢? 这个就依靠每个节点内部维护一个路由表;

route命令用于查看路由表

查找过程:eg:有一个目的IP10.0.10.0,先与子网掩码按位与操作,得到的网络号与Destination对比,如果相同则就是下一跳,如此往复对比路由表,如果所有的表中都没有目的地址,那么会选择默认路由。

以上是关于网络层——IP协议的主要内容,如果未能解决你的问题,请参考以下文章

Java-----网络编程

地址解析协议ARP与逆地址解析协议RARP

计算机网络—— 网络层(789):IPv4数据报的首部格式网际控制报文协议ICMP虚拟专用网VPN与网络地址转换NAT

IP分组

网络层——IP协议

网络层协议介绍