IP协议

- 主机:配有IP地址,但是不进行路由控制的设备
- 路由器:即配有IP地址,又能进行路由控制
- 节点:主机和路由器的统称;
IP协议/网络层,做的工作,主要是两个:
- 地址管理:使用IP地址,这样的概念,标识网络上的某个设备的位置;
- 路由选择:在两个通信的节点之间,规划出一个合理的路径;
协议头格式

-
4位版本号:指定IP协议的版本,对于IPv4来说,就是4位字节。开发阶段,主要针对IPv4,IPv6近几年才多起来。
-
4位部首长度:IP协议的报头,也是变长的。单位都是4字节。4bit表示最大的数字是15,因此IP头部最大长度是60字节。
-
8位服务类型:决定了IP协议的工作方式;3位优先权字段(已经弃用),4位TOS字段,和1位保留字段(必须置为0).4位TOS分别表示:最小延时,最大吞吐量,最高可靠性,最小成本(也有api可以用来设置,开发中很少直接涉及到,砸门Java程序员主要写web类应用)。这四者相互冲突,只能选择一个。对于ssh/telnet这样的应用程序,最小延时比较重要;对于ftp这样的程序,最大吞吐量比较重要。
-
16位总长度:一个IP数据报 报头+载荷的长度(64KB。IP协议内置了拆包组包的功能,比如IP携带一个比较大的TCP数据报,IP协议就会自动拆成多个,通过多个IP数据报共同传输一个TCP数据报)
-
16位标识(id): 唯⼀的标识主机发送的报⽂. 如果IP报⽂在数据链路层被分⽚了, 那么每⼀个⽚⾥⾯的这个id都是相同的.
-
3位标志字段: 第⼀位保留(保留的意思是现在不⽤, 但是还没想好说不定以后要⽤到). 第⼆位置为1表⽰禁⽌分⽚, 这时候如果报⽂⻓度超过MTU, IP模块就会丢弃报⽂. 第三位表⽰"更多分⽚", 如果分⽚了的话, 最后⼀个分⽚置为1, 其他是0. 类似于⼀个结束标记.
-
13位分⽚偏移(framegament offset): 是分⽚相对于原始IP报⽂开始处的偏移. 其实就是在表⽰当前分⽚在原报⽂中处在哪个位置. 实际偏移的字节数是这个值 * 8 得到的. 因此, 除了最后⼀个报⽂之外, 其他报⽂的⻓度必须是8的整数倍(否则报⽂就不连续了).
-
如果基于UDP实现传输超过64KB的数据,该怎样设计?
参考IP的方案。应用层协议中,就可以指定标识符,指定片偏移,指定标志位。
-
8位生存时间(TTL):数据报到达目的地的最大报文跳数,单位是"次数",一般是64。IP数据报每次经过一个路由器转发一次,TTL的值就-1,一直减到0还没到达,就说明包到不了,就要被丢弃掉。这个字段主要是用来防止出现路由循环。(比如发了一个错误的数据包(目的IP写错了),注定是不可能到达的,这个包也不能无限传输。还有一种明明地址是对的,通过64次转发下来,还是到不了对方呢?这个理论上存在,实际上可能性不大。1,64可能设置成更大的值,128~ 2.其实网络中,有一个"六度空间"这样的理论,两个设备之间,不需要那么多次转发,就足够了。)
-
8位协议:标识传输层(上层)使用哪种协议。分用的时候,IP协议解析IP数据报的时候,拿到载荷,交给上层处理。此处8位协议编号,就能起到区分效果。(传输层到应用层⇒端口号,网络层到传输层⇒8位协议,数据链路层到网络层⇒也有一个类似的协议编号)
-
16位首部检验和:使用CRC进行校验,来鉴别头部是否损坏。
-
32位源IP地址和32位目的IP地址 :表示发送端和接收端。IP协议最关键的部分,IP地址本质上是通过32位的整数来表示的,由于32整数不方便阅读,通常会把IP写作点分十进制表示方式(用三个点,分出四个部分,每个部分用0~255表示)
-
选项字段:不定长,最多40字节。略
地址管理
我们知道IP地址(IPv4)是一个4字节32位bit的正整数,那么一共只有2的32次方个IP地址,大概是43亿左右。而TCP/IP协议规定,每个主机都需要有一个IP地址,这也就意味着,一共只有43亿台主机能接入网络。但是,站在现在来看,确实有点捉襟见肘了。而且,由于一些特殊的IP地址的存在,数量远不足43亿;另外IP地址并非是按照主机台数来配置的,而是每一个网卡都需要配置一个或多个IP地址。
-
那IP不够用了,该怎么办呢??
-
动态分配IP地址:只给接入网络的设备分配IP地址。也就是上网再分配,不上网就不分配。因此,同一个MAC地址的设备,每次接入互联网中,得到的IP地址不一定是相同的。
-
NAT机制:网络地址转换[当前网络世界的最主要的方式]
把所有的IP分为两个大类:
- 公网IP/外网IP:公网IP是唯一的。
- 私网IP/内网IP:私网IP再不同的局域网中,可以重复。(以 10.* 或者 172.16-172.31.* 或 192.168.* 开头的称为私网IP)
NAT机制,就可以用一个外网IP对应到一系列的内网的设备。一个设备有一个独立的局域网 IP(允许重复),但是多个设备共用一个外网IP(不允许重复)。
-
IPv6[最终方案]:IPv6并不是IPv4的简单升级版,这是互不相干的两个协议。IPv4是使用4个字节作为IP地址(2的32次方),IPv6是使用16个字节作为IP地址(2的128次方),而且,最重要的一个点是IPv6和IPv4不兼容,要升级成IPv6就得更换设备(路由器),换路由器就得花钱,但升级IPv6不能提高任何的上网体验,所以费力不讨好。目前的现状:全世界,IPv6的普及程度,非常非常低,但是中国是IPv6普及程度最高的国家(没有之一)。
-
-
NAT背景下,网络通信如何进行?
-
同一个局域网下,设备A访问设备B;
由于IP本身不允许重复,自然不受影响,NAT不起到作用。
-
公网设备A 访问 公网设备B;
由于公网IP本身也不重复,也不受到影响,NAT不起作用。
-
不同局域网,设备A访问设备B;
是不允许的!!NAT机制禁止这样的访问方式。
-
局域网设备A访问公网设备B;
通过网络地址映射
注意:不是带有公网IP就一定触发NAT,也是得看本来的源IP是不是私网IP。
局域网中的若干个设备,共用一个公网IP。本来一个设备一个公网IP,不够用。若干个设备共用一个公网IP,就够用了。现实中,一个公网IP背后代表着几千个,上万个局域网设备。
但是呢,现在还有一个问题,我现在把数据通过网络传到服务器了,那服务器的响应该怎么找回来呢?
这就不得不提网络通信"五元组了"(源IP,目的IP,源端口,目的端口,协议类型),IP协议里的报头存有源IP目的IP,载荷里面存有源端口,目的端口。此处就可以通过端口号进一步进行区分。
那又有问题了?万一两个客户端的端口号一样了怎么办呢?(极小概率)
针对这个问题,我们需要知道一些知识点:
- 路由器触发NAT地址替换的时候,自身维护一个"哈希表"结构,记录替换的映射关系
- NAT设备进行替换的时候,端口号是可以随意进行修改的。
- 端口号是用来区分同一个主机上的不同程序,但是也可以用来区分不同主机上的不同程序。
-
公网设备A,尝试访问局域网设备B;
不允许的!但是特殊手段可以。你在你电脑上搭一个能让外网访问的服务器需要特殊手段的,比如内网穿透,通过VPN(虚拟私人网络),这些不和NAT冲突,本质上都是借用其他的带有公网IP的设备进行转发。
VPN也是类似的过程。
-
网段划分
把一个IP地址,分为两个部分。前半部分,称为"网络号",后半部分,称为"主机号"。
- 网络号:保证互相连接的两个网段具有不同的标识;
- 主机号:同一网段内,主机之间具有相同的网络号,但是必须有不同的主机号。
- 同一个局域网中,网络号必须相同,主机号必须不同。
- 两个相邻的局域网中,网络号必须不同,主机号无限制。

-
相邻的局域网
一个路由器有两个IP(WAN,LAN),这两IP就在两个不同的局域网中。路由器的功能就相当于把两个局域网连接到一起了。
一般来说,电脑插到路由器上,就可以自动获取到一个合法的IP,也可以主动设置。
如果你手动把IP的网络号设成一样的,也就会导致网络不通。
有一个问题,手动管理子网内的IP,是一个相当麻烦的事情。
- 有意者技术叫做DHCP,能够自动的给子网内新增主机节点分配IP地址,避免了手动管理IP的不便。
- 一般的路由器都带有DHCP功能,因此路由器也可以看做一个DHCP服务器。
过去(现在不用了)曾经提出一种划分网络号和主机号的方案,把所有IP地址分为五类,如下图所示:

但随着Internet的⻜速发展,这种划分⽅案的局限性很快显现出来,⼤多数组织都申请B类⽹络地址, 导致B类地址很快就分配完了, ⽽A类却浪费了⼤量地址;
- 例如, 申请了⼀个B类地址, 理论上⼀个⼦⽹内能允许6万5千多个主机. A类地址的⼦⽹内的主机数更多。
- 然⽽实际⽹络架设中, 不会存在⼀个⼦⽹内有这么多的情况. 因此⼤量的IP地址都被浪费掉了。
因此针对这种情况提出了新的划分方案,称为CIDR(Classless Interdomain Routing):
-
引入一个额外的子网掩码来区分网络号和主机号;
-
子网掩码也是一个32位的正整数,通常用一串"0"来结尾;
-
将IP地址和子网掩码进行"按位与"操作,得到的结果就是网络号;
-
网络号和主机号的划分与这个IP地址是A类,B类还是C类无关。
可见,IP地址与子网掩码做与运算可以得到网络号,主机号从全0到全1就是子网的地址范围。
在cmd上用 ipconfig 也可以看自己电脑的IP地址和子网掩码。
特殊的IP地址
- 将IP地址中的主机地址全部设为0,就成为了网络号,代表这个局域网;
- 将IP地址中的主机地址全部设为1,就成为了广播地址,用于给同一个链路中相互连接的所有主机发送数据包;
- 127.*的IP地址用于本机换回(loop back)测试,通常是127.0.0.1;
上面是强制要求的,但还有一些习惯用法。就比如主机号为1的ip(192.168.20.1)在IP协议中,只是普通IP,在实际组网中,通常使用这个IP作为网关IP。
网关IP:网络的入口/出口。(家庭网络中,网关一般就是路由器,大型的企业/网络结构,网关通常是单独的物理设备)
路由选择
就是通过IP协议,进行数据转发的过程;
只是这个转发过程,极其复杂,在这里只讨论简化的模型。(深入讨论,需要理解广域网网络环境的组织,但每个运营商都有自己的技术架构,没有统一标准)
IP数据包的传输过程和问路一样:
- 当IP数据包,到达路由器时,路由器会先查看目的IP;
- 路由器决定这个数据包是能够直接发给目标主机,还是需要发送给下一个路由器;
- 依次反复,一直到达目标IP地址;
那么如何判定当前这个数据包该发送到哪⾥呢? 这个就依靠每个节点内部维护⼀个路由表;

这里谈到的路由选择,对于路由器来说,也是这样的。
我们知道网络环境是非常复杂的环境,任何一个路由器,无法储存所有的网络信息的,但是每个路由器,是可以知道附近的网络情况(至少知道谁和它相连)。
当数据包到达某个路由器的时候,就会匹配这个路由器的"路由表"(路由表就记录了这个路由器周围的设备的IP是啥,以及也会记录每个设备要通过哪个口转发过去)。
- 如果目的IP刚好匹配到了路由表中的记录,直接按照当前的对应的口转发过去就行了
- 如果没有匹配到,路由表就会有一个特殊的表项,"下一跳"。"下一跳"所指向的设备,就是上一级路由器所在的位置。(这些路由器,越往上涵盖的范围就越大)
路由表可以用 route 命令查看;

- 这台主机有两个⽹络接⼝,⼀个⽹络接⼝连到192.168.10.0/24⽹络,另⼀个⽹络接⼝连到 192.168.56.0/24⽹络;
- 路由表的Destination是⽬的⽹络地址,Genmask是⼦⽹掩码,Gateway是下⼀跳地址,Iface是发送接 ⼝,Flags中的U标志表⽰此条⽬有效(可以禁⽤某些 条⽬),G标志表⽰此条⽬的下⼀跳地址是某个路由器的地址,没有G标志的条⽬表⽰⽬的⽹络地址是与本机接⼝直接相连的⽹络,不必经路由器转发;
数据链路层
认识以太网
以太网不是一种具体的网络,而是一种技术标准;既涵盖了数据链路层的内容,也包含了一些物理层的内容。例如:规定了网络拓扑结构,访问控制方式,传输速率等;
说到这可能还是有点懵,其实但凡你电脑通过 网线 这种方式上网,走的协议,就是以太网。
以太网数据帧格式
以太网数据帧格式如下图所示:


- 目的地址和源地址指的是网卡的硬件/物理地址(也叫MAC地址),长度是48位,是在网卡出场时固化的;
- 帧协议类型字段有三种值,分别对应IP,ARP,RARP;
- 帧末尾是CRC校验码;
认识MAC地址
-
MAC地址是用来识别数据链路层中相连的节点;
-
长度为48位,即6个字节,一般用16进制数字加上冒号的形式来表示;
-
可以用 ipconfig /all 命令来查找MAC地址;
-
在网卡出厂时就确定了,不能修改,MAC地址通常是唯一的,因此MAC地址也可以作为一个电脑的身份标识。(虚拟机中的MAC地址不是真实的MAC地址,可能会冲突,也有些网卡支持用户配置MAC地址。)
-
IP地址和MAC地址有啥区别?为啥有了IP还要有MAC呢??
其实理论上来说,网络通信中,有一组地址,就够了。但是最初构建网络层协议的大佬和构建数据链路层协议的大佬,不是一伙人。于是,干脆就全都要,IP就专门给网络层使用,MAC专门给数据链路层使用。程序员日常开发的时候,基本都是和IP打交道,不会涉及到MAC。
-
IP是在网络层使用,关注于整个网络路径的转发传输过程;
-
MAC是在数据链路层使用,关注于转发的细节,两个相邻设备之间的转发;
-
认识MTU
MTU相当于发快递时对包裹尺寸的限制。这个限制是不同的数据链路对应的物理层产生的限制。也就是MTU和通信的硬件结构相关的。
- 以太网帧的数据长度规定最小46字节,最大1500字节(1kb多),APR数据包的长度不够46字节,要在后面补填充位;
- 最大值1500称为以太网的最大传输单元(MTU),不同的网络类型有不同的MTU;
- 如果一个数据包从以太网路由到拨号链路上,数据包大于拨号链路的MTU了,则需要对数据包进行分片;
- 不同的数据链路层标准的MTU是不同的;
- IP数据报报头16位长度,最多64KB,在数据链路层这里要求要跟高,1kb多一点就存不下了,所有IP数据报的拆包组包,更多的时候都是因为数据链路层的限制,产生的拆包;
APR协议
APR不是一个单纯的数据链路层的协议,而是一个介于数据链路层和网络层之间的协议;
APR作用:
-
APR不是传输业务数据的,而是打辅助的协议。功能是根据IP地址,得到对应的MAC地址,也就是建立了主机IP地址和MAC地址的映射关系。
-
网络传输过程中,网络这一层,转发是要根据IP的,数据链路层这一层是要根据MAC,写代码的时候,填写的肯定是IP地址,路由器也是根据IP地址查路由表,根据路由表得到接下来哪个网口转发,此时往往就需要根据下一个节点的IP,找到对应的MAC,才能填写以太网数据帧;
重要应用层协议DNS(Domain Name System)
DNS是一整套从域名映射到IP的系统,当然可以认为是一个应用层协议,也可以认为是一套系统。
DNS底层使用UDP进行解析,浏览器会缓存DNS结果。
DNS域名解析系统,网络上的服务器,都是有IP地址的。
域名:就是一串单词。 计算机会自动把这船单词,翻译成IP地址。
最初DNS是通过hosts文件实现映射的,但hosts文件,维护起来太复杂了,所以就把hosts文件中的内容,提取出来,单独放到一个服务器上,这样的服务器就成为DNS服务器。hosts文件的功能依然存在,优先级比DNS更高,主要的用途,就是在程序测试上。

用户的电脑访问某个网站的时候,就会先查询DNS服务器,把域名对应的ip拿到,在真正访问服务器。

全世界上网的设备这么多,如果每次发起网络请求,都需要先访问DNS服务器的话,DNS服务器就要承担海量的并发量,那岂不是就会挂了吗?该如何解决上述方案?
-
缓存:
你的电脑不会在每次请求服务器的时候都出发DNS请求。比如访问sougou.com,进行一次DNS之后,就把IP记录下来了,下次再访问搜狗,就不需要重新访问DNS了。
缓存是为了减少请求次数,提高效率。Cookie只是存了数据,不能减少请求次数,也不是用来提高效率(引入大量的Cookie会降低效率)。
-
DNS的服务器可以不只有一个,而是由很多~
储存原始数据的DNS服务器称为"DNS根服务器"(全世界只有11个根服务器,大部分都在美国人手里),各种网络运营商,可以搭建"DNS镜像服务器"(时不时会从DNS根服务器拷贝一下)。此时全世界各地都有DNS服务器,国内,三大运营商,都会在各个地区,搭建DNS服务器。(IPv6就需要搭建新的DNSv6的域名解析系统)
DNS挂了现象就是:网页打不开,QQ能上。