应用层解决具体应用的问题,传输层解决的是两个网络进程之间数据通信以及如何通信的问题(是否需要连接?是否需要可靠传输?是否需要报文?)。
而网络层主要解决的是数据包如何从一个主机发送到另一个主机,包含 路径选择,寻址,转发,网络拥塞控制等功能。
目录
[一. IP基本概念](#一. IP基本概念)
[二. IP报头格式](#二. IP报头格式)
[2.1 4位首部长和16位总长度](#2.1 4位首部长和16位总长度)
[2.2 8位协议与16位检验和](#2.2 8位协议与16位检验和)
[2.3 生存时间与源ip目的ip](#2.3 生存时间与源ip目的ip)
[2.4 版本号](#2.4 版本号)
[2.5 标识/片偏移和标志](#2.5 标识/片偏移和标志)
[三. 网段划分](#三. 网段划分)
[3.1 子网划分](#3.1 子网划分)
[3.2 特殊IP地址与IP数量限制](#3.2 特殊IP地址与IP数量限制)
[3.3 私有IP和公有IP](#3.3 私有IP和公有IP)
[四. 路由器和路由](#四. 路由器和路由)
[4.1 路由器](#4.1 路由器)
[4.2 路由](#4.2 路由)
[五. IP分片与组装](#五. IP分片与组装)
[5.1 IP报文为何需要分片?](#5.1 IP报文为何需要分片?)
[5.2 如何进行分片和组装](#5.2 如何进行分片和组装)
[5.3 分片的意义](#5.3 分片的意义)
一. IP基本概念
IP是用于定位和标识一个主机的位置的,用于跨主机将数据传输到目的主机。 有了对方IP我们才能再网络中进行路径选择。IP就是主机在网络上的逻辑地址
IP层收到上层(传输层)的数据后,会封装一个IP报头再交付给数据链路层。IP收到下层(数据链路层)的数据后会解析出IP报头,然后将其交付给的传输层。
二. IP报头格式
传输层的TCP/UDP有自己的报头,网络层也是如此。IPV4报头格式如下:

可以看到IP的固定首部长度是:(32 * 5) / 8 = 20 字节
2.1 4位首部长和16位总长度
4位首部长:用于计算IP报头的长度,计算方式是4位首部长 * 4。 由于固定长度是20字节,所以首部长最小值是 20/4 = 5 即 0101。同理也能获取最大值 (1111) * 4 = 15 * 4 = 60字节
16位总长度:用于表示整个IP报文的长度,16位总长度 - 4位首部长 = IP有效载荷的长度。
我们知道:TCP报头中并没有一个字段表示TCP报文长度,一般使用IP的有效载荷长度来表示TCP报文的长度
2.2 8位协议与16位检验和
8位协议:用于表示交付给上层的是何种协议,比如UDP/TCP。
16位检验和:用于检测IP报文有没有损坏(数据错误或者字节数多了/少了),如果发现错误就会丢失这个IP报文
可以看到,IP层并不保证可靠性(如果上层是TCP的话,这个报文就会被重传,如果是UDP的话,报文丢失了也没事,符合UDP特性)
2.3 生存时间与源ip目的ip
8位生存时间:网络传输中,我们无法保证一个IP报文能够被对方接收,为了避免IP报文长时间无法到达对方(比如进入了环路永远无法到达地方)从而导致网络阻塞。设置了一个生存时间TTL,每当IP报文被传输到下一跳,TTL就会-1。当TTL = 0时候,这个报文就会被丢弃。
源ip和目的ip:用于标识该报文的发送方IP和接收方IP,方便寻址和每一个节点转发报文
2.4 版本号
用于标识使用的协议是IPV4还是IPV6,由于IPV4的格式只有32位,最多表示2^32 - 1 的主机。也就是4294967295,42亿个IP地址。可是目前全球人类有80多亿,一个也不可能只有一台主机。所以IPV4提供的IP地址是明显不够的
而新提出的IPV6是128位,最多提供2^128 - 1 个IP地址,远大于80亿。
这里给出IPV6的报文格式,但不过多赘述。

2.5 标识/片偏移和标志
用于IP的分片和组装,后续会详细说明
三. 网段划分
3.1 子网划分
什么是子网划分?
网段划分就类似于学校中的学号划分 2022(年份) 1100(学院/专业) 05(班级) 38(班级编号)
为什么要子网划分?
我们的IP也是一样,互联网中的每一台主机,都必须要位于某一个子网。可以通过子网定位这一台主机,通过你属于哪一个子网,可以排除大量其他IP地址。
如何进行子网划分,谁来做这个工作?
IP地址有32位,子网划分是运营商划分的(联通,电信,移动)
网络号:保证相互连接的两个网段具有不同的标识
主机号:表示同一个网络中,不同的主机具有相同的网络号,但是具有不同的网络号
路由器属于不同的网段,所以路由器具有不同的ip地址,通常是网段子网号.1
每一个子网中新增一台主机,这台主机的网络号必须与子网的网络号相同。那么这些子网内的ip地址是不是需要管理呢?
子网内的ip地址的管理是由内部的DHCP完成的
由于A类B类C类这样划分子网会导致浪费大量的IP地址,引入了一个子网掩码概念
网络号 = ip地址 & 子网掩码
目标网络和子网掩码,子网中的主机,都会由路由器管理
3.2 特殊IP地址与IP数量限制
0.0.0.0表示局域网,1.1.1.1表示广播地址。127.0.0.1表示本地回环地址
为了解决IP地址的数量限制,目前有下面这些技术:
1 动态分配IP地址(DHCP),只给接入网络的主机分配IP,不接入网络只有MAC地址。这样就能缓解IP数量限制,不过这样一台主机可能会有多个不同的IP地址
2 NAT技术:将网络分为内网和公网,通过内网IP->公网IP来缓解IP数量限制
3 IPV6:拥有2^128-1个IP地址,是解决IPV4地址不够的终极方案。不过目前全球还没有完全推广
3.3 私有IP和公有IP
如果一个局域网内部组织网络,IP地址只用于局域网内中通信。理论上来说,可以随意使用任意的IP地址。但是官方规定了:
以10*开头的
172.16 到 172.31
192 168 *
只能用上面的三类IP地址来建立私有IP,其他的都是公网IP。
我们访问服务器,必须要通过运营商的路由,然后访问目的IP地址。所以 翻墙翻的就是绕过运营商访问外网IP
四. 路由器和路由
4.1 路由器
路由器是用于路由(转发),NAT(内网与公网转换),DHCP(动态分配IP地址)的装置。可以用于组建局域网,不过组建的时候只能使用内网IP。
路由器一般有两个IP,分别为LAN口IP和WAN口IP。LAN口IP是子网IP,用于对内的,WAN口IP是用于对外的
子网中的主机想要对外通信,路由器需要将IP首部的IP地址替换为WAN口IP,然后逐级替换,最后数据包中的IP地址就是公网IP。这种技术就是NAT技术
4.2 路由
主机向其他主机发送数据时候:
1 不知道目的IP在哪,也不知道路由器在哪:这种情况直接将数据发送给默认路由器进行路由
2 不知道目的IP在哪,但是知道某一个路由器A知道:将数据发送给路由器A
3 知道目的IP在哪,说明目的IP就在我的子网中:直接将数据发送给对应主机
我们使用route命令,即可查看路由表:

五. IP分片与组装
5.1 IP报文为何需要分片?
IP报文的最长长度是 2^16 -1 = 65535字节。IP的有效载荷最长长度是 65535 - 20 - 65515字节。相对的:TCP报文有效载荷最长是65535 - 20 - 20 = 65495字节,UDP最长有效载荷是65535 - 20 - 8 = 65,507字节。
虽然你们都很长,但是数据链路层却规定了自己的MAC协议帧,明确表示一个帧的有效载荷不可超过1500字节(MTU单元)。
这就表示,IP报文(报头+有效载荷)不可超过1500字节。
不过实际上,IP报文的长度不并由IP网络层决定。而是由传输层TCP/UDP决定,如果传输层发送了一个数据报长度是6666字节,IP层该怎么办?
之前提到的标识/片偏移和标志就是用于实现IP分片和组装的。
分片:当TCP/UDP报文长度超过1500字节时候就需要分片,由自己完成
组装:由对方主机的IP层完成。
传输层:TCP/UDP不关心IP是否分片,只关心自己有没有收到一个完整的报文
数据链路层:MAC帧不关心自己是否分片,只关心自己MAC帧传输到下一个主机
5.2 如何进行分片和组装
1 同一个报文的不同分片如何区分,比如首个分片,中间分片,最后分片?
标志和片偏移:用于标记某一个ip是否分片 标识:标识相同的ip报文分片,属于同一个IP数据报
没有分片:标志MF和片偏移Offset都为0
如果分片:
首个分片:标志MF是1,片偏移Offset是0
中间分片:标志MF是1,片偏移Offset > 0
最后分片:标志MF是0,片偏移Offset > 0
2 如何保证识别报文的先后顺序?
接收方通过标识将相同的ip分片组合在一起,通过片偏移来排序这些ip分片
3 如果由ip分片丢失了呢?如何解决
使用当前分片的起始地址 + 当前分片长度找到写下一关分片的片偏移,当发现不对之后这个ip数据报就会丢弃。然后UDP直接丢弃报文,TCP会重传
4 如何确定组装的IP数据报是正确的?
如果经过IP检验/TCP检验和/UDP检验和,都没有出错。该报文就是正常的,如果出错了就根据不同协议的规定处理即可
16位标识:如果IP报文因为MTU分片了,相同报文的每一个分片的标识位是相同的
3位标志:第一1暂时不用,第二个标志位标识静止分片(为1的话,如果报文过大直接丢弃该报文)。第三标志位表示"更多分片",为1表示该分片后面还有分片,为0代表该分片是该报文的最后一个分片(即分片了的报文最后一个这位是0,其他分片是1)
13位分片片偏移:表示这个分片的是相对于原始IP数据报开始处的偏移量。即表示分片在原始报文的位置
5.3 分片的意义
分片是为了数据链路层更好的传输数据,通过分片我们虽然能保证数据有效传输,但是也会带来更多的操作和错误。(比如分片,组装需要时间,一个分片出错整个报文就丢失了)
所以我们正常写代码的情况下,能够减少TCP/UDP报文长度的情况下,尽量控制报文长度为1500字节以下,减少IP分片,提高通信效率
