我们根据前面的学习,知道:
1、HTTP:是用来构建与解析 request && response -》调用recv和send来解决自己的问题。注意,这里的recv和send是tcp提供的接口。
2、TCP :可靠性、效率、什么时候发送、怎么发、发多少
3、IP:解决端到端、点到点的问题。将数据经过路径选择、送达对方主机的过程——IP负责
4、主机: 配有IP地址, 但是不进行路由控制的设备; 路由器: 即配有IP地址, 又能进行路由控制; 节点: 主机和路由器的统称;
IP报头
我们同样采用列点式来进行分析:
IP也是需要解决两个最基本的问题:实现数据和有效载荷分离以及交付给上层哪一个协议的问题。
1、我们在IP报文中的8位协议即解决交付给上层的哪一个协议。
2、在IP中的四位首部长度即为解决数据报头和有效载荷分离的问题。(并且这一点和TCP是一样的)
3、4为版本基本就是IPV4.(相对于IPV6)
4、8位服务类型:在最小延时, 最大吞吐量, 最高可靠性, 最小成本 这四个选项当中选一个(四者本身相互冲突,所以只能够选一个)。就是选择哪一个优先的问题
5、8位生存时间:真正在网络上面跑的都是一个个IP报文。这里的生存时间 的作用就是如果生存时间到了,那么就将该报文丢弃。(例如每经过一个路由器,生存时间就--,当其为0的时候,就直接丢弃,为了防止游离报文被无限循环转发,浪费网络资源)(如果要发送的很远,会有极限器将你的数据报文信号放大)
6、16位首部校验和:校验首部。(TCP校验的是校验整个,IP不需要,因为这属于可靠性的问题,是属于TCP管的)
7、32位源IP和32位目的IP:
我们知道,路由查找的过程是先查找到目标网络,再查找到目标主机。
源IP和目的IP分别存储着的是源IP地址和目的IP地址。
8、关于16位标识、3位标志和13位片偏移:
在MAC中,有一个MTU,即单次发送的最大值(最大发送单元),一般为1500字节,可以用ifconfig来查看。
所以,一旦数据大小超了,就要进行分片。但是呢,分片这种事情并不是底层的MAC来做,那MAC不做,就只能够是上层的IP来做喽。(即每个IP+有效载荷最大==1500)
当上层的TCP一次交付给下层的IP很大的数据时,就要逼着IP分片。并且每一个分片都要包含着一个IP报头。
这个过程叫做分片。
可是TCP并不知道这些细节。只关心当我要回来的时候,到TCP阶段也是一个完整的报文。
所以,当接收方接收到这些分片的时候,需要将其还原,重新拼接在一起。
那我们怎么办才能将其组装好交付给上层呢?
(1)先将分片的挑出来;在三位标志中有一个标志位用来表示是否被分片。
(2)将同一组的分片挑出来(即同一个发送方发送过来的);同一组的16位标识是一样的。(拷贝过来的)
(3)将一组的收集起来之后,我们将其组装起来。这里我们用13位片偏移。根据13位片偏移进行排序,将其重新拼接起来。
并且假如中间有一个报文丢了,我们也能够很快速的识别出来。(如果一个丢了,那么这整个报文就会需要全部重发,因为TCP是不关心底层IP分片的,它没有能力去识别出具体哪个丢了哪个没丢)
按照这种理解方式,我们实际在检测的时候,首先检测13位片偏移,当片偏移不为0那其一定就是被分片的;而如果其为0,如果其为第一片,那么其更多分片的标志位就会被设置为0。
仅当片偏移为0并且更多标志位为1的时候,才标识其为未分片
网段划分
IP地址分为两个部分, 网络号和主机号
网络号: 保证相互连接的两个网段具有不同的标识;
主机号: 同一网段内, 主机之间具有相同的网络号, 但是必须有不同的主机号;
如上图是由一个路由器连接的两个不同的局域网。
而路由器在每个局域网当中也需要配备IP。(如上分别为192.168.128.x 和192.168.144.x)
一个IP地址是可以由4个字节,32个比特位来表示的
上图的/24表示的是前24个都是1,后8个是0的子网掩码,具体点说,就是其子网掩码为255.255.255.0
通过合理设置主机号和网络号, 就可以保证在相互连接的网络中, 每台主机的IP地址都不相同.
那么问题来了, 手动管理子网内的IP, 是一个相当麻烦的事情.【IP地址分配】
有一种技术叫做DHCP, 能够自动的给子网内新增主机节点分配IP地址, 避免了手动管理IP的不便.
一般的路由器都带有DHCP功能. 因此路由器也可以看做一个DHCP服务器.
过去曾经提出一种划分网络号和主机号的方案, 把所有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地址都被浪费掉了.
针对这种情况提出了新的划分方案, 称为CIDR(Classless Interdomain Routing):
引入一个额外的子网掩码(subnet mask)来区分网络号和主机号;
子网掩码也是一个32位的正整数. 通常用一串 "0" 来结尾;
将IP地址和子网掩码进行 "按位与" 操作, 得到的结果就是网络号;
网络号和主机号的划分与这个IP地址是A类、B类还是C类无关;
可见,IP地址与子网掩码做与运算可以得到网络号, 主机号从全0到全1就是子网的地址范围;
IP地址和子网掩码还有一种更简洁的表示方法,例如140.252.20.68/24,表示IP地址为140.252.20.68, 子网掩码的高24位是1,也就是255.255.255.0(刚刚说过)
注意:如果主机号为全0,我们一般叫做网段号(或者网关号,即局域网的入口号);如果为全1,我们一般叫做广播号
私有IP地址和公网IP地址
10.*,前8位是网络号,共16,777,216个地址
172.16.到172.31.,前12位是网络号,共1,048,576个地址
192.168.*,前16位是网络号,共65,536个地址
包含在这个范围中的, 都成为私有IP, 其余的则称为全局IP(或公网IP)
所以私有IP在不同的局域网中可能重复
我们这里来区分一下目的IP和源IP
(1)假如我们有一个数据,从上述画红圈的地方发送到122.77.241.3/24中去,那应该怎么发?
首先,从主机到家用路由器:
源IP:192.168.1.200 /24 目的IP:122.77.241.3/24
从家用路由器到运营商路由器:
源IP:10.1.1.3/24(WAN口IP作为其源IP地址) 目的IP:122.77.241.3/24
从运营商路由器到目标主机:
源IP:122.77.241.4/24 目的IP:122.77.241.3/24
(2)从上述过程可以看出,在这个过程当中,源IP是在不断发生变化着的。
这个过程就是数据从局域网到公网当中的过程。这种技术就叫做NAT技术。(更改的是源IP地址)
(3)为什么要这么做呢?首先,私有IP不能出现在公网中,因为在不同的局域网当中,IP可能重复。如果你发出去的是一个私有IP,那返回来的时候目的IP怎么填呢?
(4)NAT技术很好地解决了IP地址不足的问题。
(5)那数据回来呢?我们这个过程我们需要查表。(即在数据出去的过程当中在路由器中是会建立一张映射关系表的)
补充一下路由器 的有关知识:
(1)一个路由器可以配置两个IP地址, 一个是WAN口IP, 一个是LAN口IP(子网IP)。路由器LAN口连接的主机, 都从属于当前这个路由器的子网中.
(2)不同的路由器, 子网IP其实都是一样的(通常都是192.168.1.1). 子网内的主机IP地址不能重复. 但是子网之间的IP地址就可以重复了.
(3)每一个家用路由器, 其实又作为运营商路由器的子网中的一个节点. 这样的运营商路由器可能会有很多级,最外层的运营商路由器, WAN口IP就是一个公网IP了.
(4)子网内的主机需要和外网进行通信时, 路由器将IP首部中的IP地址进行替换(替换成WAN口IP), 这样逐级替换, 最终数据包中的IP地址成为一个公网IP. 这种技术称为NAT(Network Address Translation,网络地址转换)(上面说到过)。
(5)如果希望我们自己实现的服务器程序, 能够在公网上被访问到, 就需要把程序部署在一台具有外网IP的服务器上. 这样的服务器可以在阿里云/腾讯云上进行购买.
路由
路由的过程, 就是这样一跳一跳(Hop by Hop) "问路" 的过程.
所谓 "一跳" 就是数据链路层中的一个区间. 具体在以太网中指从源MAC地址到目的MAC地址之间的帧传输区间
当IP数据包, 到达路由器时, 路由器会先查看目的IP;
路由器决定这个数据包是能直接发送给目标主机, 还是需要发送给下一个路由器;
依次反复, 一直到达目标IP地址;
查看我的路由表
第一个是目的网络,GeteWay表示下一跳,Genmask表示子网掩码。
目的IP与子网掩码按位与,如果与目的网络的IP匹配上,那么就送到相应的网段中。如果没有,那就送到默认路由路径(默认网关)