【网络层】网络基础 -- IP协议

引入

我们前面学习了传输层的相关知识,难道真的就是直接传送吗?当然不是,那TCP究竟做了什么?IP又扮演什么角色?

IP层的核心工作:

IP地址的作用:定位主机的,具有一个将数据报从A主机跨网络送到B主机的能力。

那么有能力就一定能做到吗?比如一个同学数学非常好,考了很多次的数学满分,我们可以说他有考数学满分的能力,有很大概率考满分,但是他一定能做到吗?


IP

IP:将数据从A主机跨网络到B主机的能力

比如我们要从吐鲁番到北京去游玩,我们没有从吐鲁番直达北京的能力,那么我们就需要选择路径去一个一个转达最后到北京,最终目的地就是北京。

  1. 路径选择中,目标IP非常重要,决定了我们的路径该如何走
  2. ip = 目标网络+目标主机 (比如我们去北京游玩肯定是要去北京某个具体的地方,比如故宫、天安门广场等,而北京可以理解成目标网络,而北京故宫理解为目标主机为具体某一地方)

先看一个生活案例:

每个学生的学号都设计过的,假如学号为:学院号+学生编号

正如上述,互联网也是类似,互联网中的每一台主机,都要隶属于某一个子网。目的是为了方便定位这个主机,这样查找的时候效率高(排除效率高)。这也就是子网划分的目的。


协议头格式

  • 4位版本号(version):指定IP协议的版本,对于IPv4来说,就是4

  • 4位头部长度(header length):IP头部的长度是多少个32bit,也就是 length * 4 的字节数。 4bit表示最大的数字是15,因此IP头部最大长度是60字节

  • 8位服务类型(Type Of Service):3位优先权字段(已经弃用),4位TOS字段,和1位保留字段(必须置为0)。

  • 4位TOS分别表示:最小延时,最大吞吐量,最高可靠性,最小成本。这四者相互冲突,只能选择一个。对于ssh/telnet这样的应用程序,最小延时比较重要。对于ftp这样的程序,最大吞吐量比较重要

  • 16位总长度(total length):IP数据报整体占多少个字节

  • 16位标识(id),3位标志字段,13位分片偏移(framegament offset):在目录的分片与组装会说明

  • 8位生存时间(Time To Live, TTL):数据报到达目的地的最大报文跳数,一般是64。每次经过一个路由,TTL -=1, 一直减到0还没到达,那么就丢弃了。这个字段主要是用来防止出现路由循环

  • 8位协议:表示上层协议的类型

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

  • 32位源地址和32位目标地址:表示发送端和接收端

  • 选项字段(不定长, 最多40字节):略


网段划分

IP地址分为两个部分,网络号和主机号

  • 网络号:保证相互连接的两个网段具有不同的标识
  • 主机号:同一网段内,主机之间具有相同的网络号,但是必须有不同的主机号
  • 不同的子网其实就是把网络号相同的主机放到一起
  • 如果在子网中新增一台主机,则这台主机的网络号和这个子网的网络号一致,但是主机号必须不能和子网中的其他主机重复(就比如你的学院新增一名学生,那么他学号的学院号应该跟你一样,而学生编号应该是不同于这个学院的所有学生)

通过合理设置主机号和网络号,就可以保证在相互连接的网络中,每台主机的IP地址都不相同

那么问题来了,手动管理子网内的IP,是一个相当麻烦的事情

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

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

  • A类 0.0.0.0127.255.255.255
  • B类 128.0.0.0191.255.255.255
  • C类 192.0.0.0223.255.255.255
  • D类 224.0.0.0239.255.255.255
  • E类 240.0.0.0247.255.255.255

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

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

针对这种情况提出了新的划分方案, 称为CIDR(Classless Interdomain Routing):

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

划分子网例子:

IP地址 140.252.20.68 8C FC 14 44
子网掩码 255.255.255.0 FF FF FF 00
网络号 140.252.20.0 8C FC 14 00
子网地址范围 140.252.20.0~140.252.20.255
IP地址 140.252.20.68 8C FC 14 44
子网掩码 255.255.255.240 FF FF FF F0
网络号 140.252.20.64 8C FC 14 40
子网地址范围 140.252.20.0~140.252.20.79

可见,IP地址与子网掩码做与运算可以得到网络号,主机号从全0到全1就是子网的地址范围;IP地址和子网掩码还有一种更简洁的表示方法,例如140.252.20.68/24,表示IP地址为140.252.20.68,子网掩码的高24位是1,也就是255.255.255.0

特殊的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地址

这意味着,一共只有43亿台主机能接入网络么?

实际上,由于一些特殊的IP地址的存在,数量远不足43亿;另外IP地址并非是按照主机台数来配置的,而是每一个网卡都需要配置一个或多个IP地址

CIDR在一定程度上缓解了IP地址不够用的问题(提高了利用率,减少了浪费,但是IP地址的绝对上限并没有增加),仍然不是很够用,这时候有三种方式来解决:

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

私有IP地址和公网IP地址

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

  • 10.*,前8位是网络号,共16,777,216个地址(企业路由器)
  • 172.16.172.31.,前12位是网络号,共1,048,576个地址(企业路由器)
  • 192.168.*,前16位是网络号,共65,536个地址 (家用路由器)
    包含在这个范围中的,都成为私有IP,其余的则称为全局IP(或公网IP)
  • 一个路由器可以配置两个IP地址,一个是WAN口IP, 一个是LAN口IP(子网IP)

    WAN口IP对外,LAN口IP对内

  • 路由器LAN口连接的主机,都从属于当前这个路由器的子网中

  • 不同的路由器,子网IP其实都是一样的(通常都是192.168.1.1)。子网内的主机IP地址不能重复,但是子网之间的IP地址就可以重复了

  • 每一个家用路由器,其实又作为运营商路由器的子网中的一个节点,这样的运营商路由器可能会有很多级,最外层的运营商路由器,WAN口IP就是一个公网IP了

  • 子网内的主机需要和外网进行通信时,路由器将IP首部中的IP地址进行替换(替换成WAN口IP),这样逐级替换,最终数据包中的IP地址成为一个公网IP,这种技术称为NAT(Network Address Translation,网络地址转换)

  • 如果希望我们自己实现的服务器程序,能够在公网上被访问到,就需要把程序部署在一台具有外网IP的服务器上,这样的服务器可以在阿里云/腾讯云上进行购买

子网划分概念图:(具体划分是根据地区本图只是大致方向)

分片与组装

数据链路层,MAC帧协议,自己的有效载荷不能超过1500字节(MTU,可以修改的)

单个报文(IP报头+IP报文的有效载荷)不要超过1500字节 -- MAC帧的有效载荷

IP能决定单个报文的大小吗?不能,在网络中决定单个报文大小的是TCP,它是传输控制协议

(IP分片与组装并不是主流情况)

  • 16位标识(id):唯一的标识主机发送的报文,如果IP报文在数据链路层被分片了,那么每一个片里面的这个id都是相同的
  • 3位标志字段:第一位保留(保留的意思是现在不用,但是还没想好说不定以后要用到)。 第二位置为1表示禁止分片,这时候如果报文长度超过MTU,IP模块就会丢弃报文。第三位表示"更多分片",如果分片了的话,最后一个分片置为0,其他是1。类似于一个结束标记。
  • 13位分片偏移(framegament offset):是分片相对于原始IP报文开始处的偏移。其实就是在表示当前分片在原报文中处在哪个位置。实际偏移的字节数是这个值 * 8 得到的。因此,除了最后一个报文之外,其他报文的长度必须是8的整数倍(否则报文就不连续了)

如何分片与组装?

组装的问题:

  1. 你怎么知道一个报文被分片了?
    如果更多分片是1,就证明该标识的报文分片了
    如果更多分片是0,并且 片偏移>0 说明是分片,否则不是!
  2. 同一个报文的分片怎么被识别出来?
    16位标识
  3. 哪一个是第一个,哪一个是最后一个,怎么判定收全或者丢失?
    当前的起始位置 + 自身长度 = 下一个报文中填充的偏移量大小
  4. 哪个在前,哪个在后,如何正确的进行组装?
    只要按照片偏移进行升序排序即可
  5. 怎么保证合起来的报文是正确的?
    TCP/IP有校验和

分片好吗?

不好,一个报文被拆成多个,任意一个报文分片丢失,就会造成组装失败。而TCP与MAC都不关心进行了分片,也就导致如果出现丢失,那么必然对端要将整个报文重传。

试着分片:


如有错误或者不清楚的地方欢迎私信或者评论指出🚀🚀

相关推荐
BingoGo20 小时前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php
JaguarJack20 小时前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php·服务端
JaguarJack2 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
后端·php·服务端
BingoGo2 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
php
JaguarJack3 天前
告别 Laravel 缓慢的 Blade!Livewire Blaze 来了,为你的 Laravel 性能提速
后端·php·laravel
郑州光合科技余经理3 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
DianSan_ERP3 天前
电商API接口全链路监控:构建坚不可摧的线上运维防线
大数据·运维·网络·人工智能·git·servlet
呉師傅3 天前
火狐浏览器报错配置文件缺失如何解决#操作技巧#
运维·网络·windows·电脑
gihigo19983 天前
基于TCP协议实现视频采集与通信
网络协议·tcp/ip·音视频
QQ5110082853 天前
python+springboot+django/flask的校园资料分享系统
spring boot·python·django·flask·node.js·php