文章目录
- 一、IP协议的基本认识
- 二、IP的协议头格式
- 三、网段划分
- 四、特殊的IP地址
- 五、IP地址的数量限制
- 六、私有IP地址和公网IP地址
一、IP协议的基本认识
IP在网络分层中属于网络层协议,传输层协议里的TCP协议解决的是可靠性问题,网络层协议里的IP协议能让主机拥有将数据从本地发送到远端主机的能力。但这个能力并不一定是可靠的,也就是说有可能会出现发送失败的情况,所以我们可以结合TCP协议,也就是说,TCP/IP协议能让主机拥有将数据从本地可靠地发送到远端主机的能力。
主机指的是配有IP地址的一台独立计算机,单个主机只要它具有对应的网络层,它就具有路由控制的能力。
路由器是配有IP地址,可以进行路由控制的设备,它主要功能是在网络传输路上对数据包进行转发。
路由器和主机统称为节点。
二、IP的协议头格式
IP的协议头格式与TCP的协议头格式非常像,下面将分别介绍IP协议的协议头格式中各个字段所代表的含义。
4位版本
该字段代表的是IP协议的版本号,一般填的都是IPV4,虽然也有IPV6的IP协议,但是IPV6和IPV4是不兼容的,所以这里的四位版本字段一般填充的都是IPV4,如果是IPV6,那就是另外一套策略了。
4位首部长度
该字段代表的就是整个IP报文的长度,这里和TCP协议中的4位首部长度是一样的,理论上它的取值范围是0000~1111
,单位是4个字节,但事实上IP协议的协议报头标准长度是20个字节,所以4位首部长度的实际取值范围应该是0101~1111
。
8位服务类型(TOS)
该字段一般很少去使用,这8位中其中3位是优先权字段(已经弃用),4位是TOS字段,1位是保留字段(必须置为0)。其中4位TOS字段(Type Of Service),分别表示最小延时、最大吞吐量、最高可靠性、最小成本。这四者相互冲突,在使用时只能选择一个。比如我们将来写一些应用程序,该程序想要尽快地将数据推送到对端,比如ssh/telnet这样的程序,最小延迟比较重要。比如我们将来要写一些文件传输类的程序,比如ftp这种程序,最大吞吐量比较重要。
16位总长度(字节数)
该字段代表IP数据报整体占多少个字节。
8位协议
该字段代表上一层的协议是什么类型。
8位生存时间(TTL,Time To Live)
当数据在网络传输的过程中,由于网络出现BUG或者对端主机不可达等不可控因素的存在,有可能会导致IP报文在网络中长时间游离,而不消失,这种游离的报文到达不了对端主机,属于没有任何意义的报文了,再怎么转发也到达不了对端主机,反而还要占用网络带宽的资源。所以我们必须给IP报文设置生命周期,8位的生存时间就是IP报文的生命周期。比如把该字段设置为X,当IP报文在网络中每经过一个路由器,就将X的值减一,当X的值减到0时,就代表该报文的生命周期到了,直接可以将该报文丢弃。
32位源IP地址和32位目的IP地址
这两个字段顾名思义,分别代表的是源IP地址和目的IP地址。
16位标识、3位标志和13位片偏移
16位标识、3位标志和13位片偏移这三个字段位于IP协议报头中的第二行,这三个字段都与IP报文分片和组装有关。
数据链路层有发送单个数据帧的最大值约束,所以我们不能发送太大的IP报文。但是如果我们的IP报文很大,就需要对IP报文进行分片。这就好比寄快递的时候,有些快递公司可能规定单个包裹最大重要是多少,如果我们要寄的东西超过了这个最大重量,就没办法按单个包裹进行寄送了,只能将其进行拆分,拆分成多个包裹一起寄送。
但是分片也会出现丢包问题,如果一个IP报文被分成多个报文发出,只要其中有一个报文丢包了,在对端的网络层都不会将这个不完整的IP报文交付给传输层,而是认为该IP报文整体丢包了。显而易见的是,分片之后丢包的概率是变得更大了,所以网络层进行分片并不是主流手段,所以一般在发报文时,尽量避免IP报文分片。
下面介绍如何对IP报文进行分片。IP报文的报头中都有一个16位标识字段,这里填的是IP的序号,当对IP进行分片时,分出来的每一份IP报文都要填充原IP报文的标识。
当接收端的网络层拿到IP报文时,要进行IP报文进行组装,首先要识别哪些报文是被分片过的,然后将被分片的报文中序号相同的报文集合在一起。接收端识别报文是否是被分片的,就需要用到IP报文中的3位标志字段。3位标志字段是3个比特位,第一个比特位保留,保留的意思是现在不用,但是还没想好说不定以后要用到。第二个比特位如果被设置为1则代表禁止分片,禁止分片时如果报文的长度超过数据链路层一次能接受的最大长度,IP模块就会丢弃该报文。第三位如果被设置为1则代表更多分片,如果该IP报文被分片了,前面的所有分片报文这个第三位都设置为1,只有最后一个分片报文中这个第三位被设置为0,类似于一个结束标记。
接收端将被分片过的报文中序号相同的报文集合起来以后,就需要对报文进行组装了。这里就需要用到IP协议报头中的13位片偏移字段,该字段是分片相对于原始IP报文开始处的偏移量,其实就是表示当前分片在原报文中处在哪个位置。
接收端是如何判断接收到的IP报文哪些是被分片的呢?
首先看该报文的三位标志字段中第三位是否是1,如果是的话则代表该报文是被分片的,如果第三位是0,再看该报文的片偏移字段是否为0,如果片偏移字段不为0,则代表该报文是被分片的,并且是最后一个分片。如果片偏移字段为0,那就代表该报文不是被分片的。
接收端如何确定收集起来的相同序号的分片报文是否是完整的呢?
判断第一片分片报文是否丢了,只需要让所有的相同序号的分片报文按照片偏移量进行排序,如果排好序之后片偏移量最小的报文不是0,那么就代表第一片分片丢了。
判断最后一片报文是否丢了,只需要查看这些报文中是否没有3位标志位中第三位为0的报文,如果是的话,则代表最后一片报文丢了。
判断中间的报文是否丢了,只需要让所有的相同序号的分片报文按照片偏移量进行排序,然后从头开始遍历确认,如果片偏移量加上报文自身长度不等于下一个报文的片偏移量,则代表中间有报文丢了。
IP分片会影响传输层的TCP和UDP吗?
答案是当然会的,因为分片提高了丢包的概率,对TCP的影响可能相对少一点,因为TCP是可靠性传输,就算丢包了可以超时重传等等。但是UDP是不可靠传输的,所以对UDP影响是会比较大的。
三、网段划分
IP地址是由目的网络
+目的主机
构成的,目的网络即网络号,它保证相互连接的两个网段具有不同的标识。目的主机即主机号,在同一网段内,主机之间具有相同的网络号,但是它们的主机号必须不相同,主机号就是用来在同一网段内标识唯一主机的。IP报文在网络传输的时候,先根据IP地址的目的网络进行路由,找到目标网络。然后再根据目的主机的主机号进行数据转发。
不同的子网其实就是把网络号相同的主机放到一起,如果子网中新增了一台主机,则这台主机的网络号和这个子网的网络号必须一致,但是主机号必须不能和子网中的其它主机重复。
全球每一台电脑主机都有自己唯一的IP地址,我们的IP地址都是被划分成不同的网段的。过去曾经提出一种划分网络号和主机号的方案,把所有的IP地址分为5类,如下图所示:
这种方法叫作分类划分法,最后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
随着互联网的高速发展,这种划分方案的局限性很快显现出来了,大多数组织机构都申请B类网络地址,导致B类地址很快就分配完了,例如一个机构申请了一个B类地址,理论上一个子网可以允许有2^16次方,也就是65536台主机,但该机构只有2万个主机使用,就会导致有4万个主机名额的浪费。
针对这种情况我们又提出了新的划分方案,称为CIDR(Classless Interdomain Routing):它引入了一个额外的子网掩码,让每一个子网都配上一个子网掩码,用子网掩码来区分网络号和主机号。举个例子,假设我们的IP地址是八位的,该IP地址会配上一个也是八位的子网掩码,我们将IP地址与子网掩码进行按位与,就可以提取出该IP地址对应的网络号。
IP地址的划分可以将世界上所有的主机划分成不同的网段,通过网段的划分就可以快速地查找到该IP地址对应的主机。比如我们拿到一个需要发送的IP报文,看一看目的IP地址是什么,先从该IP地址中判断它是属于哪一个国家的,比如说判断出来是属于中国的IP地址,然后再看该IP地址属于哪个省的,再看属于哪个市的,最后一直向下定位直到找到这一台主机。网段划分就是分配IP地址资源的一种策略。
四、特殊的IP地址
- 将IP地址中的主机地址全部设为0,就成为了网络号,代表这个子网(局域网)
- 将IP地址中的主机地址全部设为1,就成为了广播地址,用于给同一个链路中相互连接的所有主机发送数据包
- 127.*的IP地址用于本机环回(loop back)测试,通常是127.0.0.1
五、IP地址的数量限制
IP地址(IPV4)是一个4字节32位的正整数,那么一共只有2^32个IP地址,大概就是43亿左右。而TCP/IP协议规定,每个主机都需要有一个IP地址,并且由于一些特殊的IP地址的存在,IP地址的数量可用的远远不足43亿。另外IP地址并非是按照主机台数来配置的,而是每一个网卡都需要配置一个或多个IP地址,比如说路由器。所以IP地址的数量是不够使用的。
CIDR在一定程度上缓解了IP地址不够用的问题,但它只是提高了IP地址的利用率,减少了浪费,并没有增加IP地址的绝对上限,所以IP地址仍然不是很够用,这时候就有三种方式来解决这个问题:
- 动态分配IP地址,只给接入网络的设备分配IP地址,不上网的设备就不给它分配IP地址,最典型的就是我们连接WIFI,只要我们一连接就会分配给我们一个IP地址,不连接的话就不会分配。但这种方法推广到公网上就不是特别适用了,因为公网上一般都是路由器或者服务器,这些都是要一直提供网络服务的。
- 使用IPV6的技术,IPV6并不是IPV4的简单升级版,这是两个互相相干的协议,彼此并不兼容。IPV6用16个字节128个比特位来表示一个IP地址,但是目前IPV6还没有完全普及。
- NAT技术
六、私有IP地址和公网IP地址
如果一个组织内部组建局域网,IP地址只用于局域网内通信,而不直接连到Internet上,理论上使用任意的IP地址都是可以的,但是RFC 1918规定了用于组建局域网的私有IP地址:
- 10.*,前8位是网络号,共16777216个地址
- 172.16.到172.31.,前12位是网络号,共1048576个地址
- 192.168.*,前16位是网络号,共65536个地址
包含在这个范围中的,都称为私有IP,其余的则称为全局IP,也叫作公网IP。
我们家里拉过网线的话应该都知道,拉网线是需要找三大运营商帮我们拉的,运营商会给我们配置好一个局域网并给我们一个路由器,每个人家里应该都有这个路由器,这个路由器就是你们家里局域网的一号主机。未来我们想通过网络访问公网服务器的时候,我们家里的路由器是不能直接将数据转发到公网的,而是要先将我们的数据转发到运营商的路由器上,运营商的路由器再帮我们把数据转发到公网上。我们不能绕过运营商,这也是为什么我们上网要给运营商交费,因为是运营商为我们搭建好的上网渠道。
- 一个路由器可以配置两个IP地址,一个是WAN口IP,一个是LAN口IP(也叫子网IP)。
- 路由器LAN口连接主机,都从属于当前这个路由器的子网中。
- 不同的路由器,子网IP其实都是一样的(通常都是192.168.1.1),子网内的主机IP地址不能重复,但是子网之间的IP地址就可以重复了。
- 每一个家用路由器,其实又作为运营商路由器的子网中的一个节点,这样的运营商路由器可能会有很多级,最外层的运营商路由器,WAN口IP就是一个公网IP了。
如果我们此时通过运营商给家里连上网络了,我们想在网络上浏览别人服务器的内容,比如想上网看个抖音,这个时候我们的请求会从主机发送到我们家里的家用路由器,源IP地址就是我们主机在局域网内的IP地址,目的IP地址就是我们要访问的服务器在公网上的IP地址。
当我们的数据转发到家用路由器之后,家用路由器需要将我们的数据进一步转发给运营商路由器,但此时我们处在的就是运营商路由器下的局域网了,如果还用我们主机在家用局域网内的IP地址的话,可能就会与其它家用局域网内的IP地址重复了,所以家用路由器会帮我们将源IP地址替换,替换成WAN口IP地址。
数据转发到了运营商的路由器,也要同样地进行这种源IP地址的替换,同样是替换成运营商路由器的WAN口IP地址,最终数据包就这样被转发到了公网中的服务器上。
这种技术称为NAT(Network Address Translation,网络地址转换)技术,这种方法可以隐性地增加IP地址的数量,因为局域网之间IP地址是可以重复的。