应用层
之前编写完了基本的 java sock,所写的所有代码都在应用层,都是为了完成某项业务
应用层也是直接和应用程序相关,程序员写代码的时候,只要涉及网络通信都可以视为应用层的一
部分
应用层里涉及到的网络通信的协议很多都是程序员自定制的
自定义协议
1.根据需求明确传输哪些信息
客户端与服务器相互传递的信息是根据需求来的
2.约定好信息组织的格式
有很多种方式,常见的有以下几种形式
(1)行文本形式
将用户的信息与服务器要传递消息放在同一行

以上图描述商家的信息为例,这种形式的响应由多行构成,每一行是一个商家每个商家中包含一些
信息,以空行来结尾
列于列之间不一定使用" , "也可以使用" ; "" . "" \t ",多个数据之间也不一定使用" \n "也可以使用
自定义的分隔符
(2)通过xml格式来约定请求和响应的数据
xml与html相似,二者都是成对的标签构成的键值对结构
xml与html区别
html标签内容都是固定的,是提前约定好的不能创建标签
xml标签内容是自定义的
xml标签变现的形式
对于一份用户信息请求
XML
<request>
<userId>1000</userId>
<position>75E75N</position>
<request>
对于一份服务器返回的响应
XML
<response>
<shop>
<id>1</id>
<name>xxx</name>
<image>1.jpq</image>
<rank>5.0</rank>
<sendprice>5</sendpricre>
</shop>
</response>
XML的优缺点
优点:可读性更高,同时相较于行文本形式节省更多空间
缺点:冗余信息太多了,网络传输中会消耗更多的宽带
(3)json当下最流行的网络数据格式组织的方案
对于一份json请求

json优缺点
优点:可读性也是很好的,消耗的宽带也比刚才的XML更节省
缺点:还是存在冗余信息
(4)protobuf
protobuf是基于二进制的格式对数据进行压缩,不涉及到json/xml冗余信息,带宽消耗最少打,可
读性就变差了
protobuf存储数据表示

protobuf约定一段二进制数据哪几个字节表示那个信息
protobuf优缺点
优点:protobuf性能更高,执行效率更高
缺点:可读性很差,开发效率降低
数据组织格式总结
1.行文本(最原始)
2.xml(比较原始,可读性好,冗余较多)
3.json(主流的方式,可读性好,冗余一般)
4.protobuf(高性能场景下使用的方式,可读性差,冗余最小)
但凡实现一个具体的程序,写代码之前一定要事先约好应用层协议的格式
其余协议
应用层的协议,除了一些自定义的协议还有一些事先约好的协议
FTP文件传输
SSH远程操控主机
telnet网络测试工具
.......
HTTP协议[重点]
HTTPS ----- HTTPS=http基础上+安全层(S表示安全层 SSL)
补充
应用层是程序员会经常接触到的,而对于传输层,网络层,数据链路层和物理层是已经由操作系
统/硬件设备实现好的
传输层
负责数据能够从发送端传输接收端
再谈端口号
端口号标识了一个主机上进行通信的不同的应用程序
端口号范围划分
- 0 - 1023: 知名端口号, HTTP, FTP, SSH等这些广为使用的应用层协议, 他们的端口号都是固定的.
- 1024 - 65535: 操作系统动态分配的端口号. 客户端程序的端口号, 就是由操作系统从这个范围分配 的.
UDP协议
UDP的特点:无连接,不可靠传输,面向数据报,全双工
UDP协议端格式

UDP的长度
整个UDP的长度等于报头+载荷,长度属性也是两个字节,表示范围是0-65535 (64KB)
由于UDP的长度有限,如何传输一个大的数据?
- 应用层代码做拆包操作.
一个大的应用层广告数据包,拆成多个小的包,使用多个 UDP 数据报传输,工作量是比较大的,写大量的逻辑,实现此处的分包组包功能并且需要进行复杂的验证 - TCP 协议. 没有数据包长度的限制.
UDP的校验和
验证数据是否发生修改的手段.
HTTPS 的数字签名, 为了防止黑客篡改 (防人)
UDP 的校验和不是为了防人,而是和安全性无关,而是防止出现传输过程中的"比特翻转"
比特翻转
光信号, 电信号, 电磁波收到外界干扰 可能会使高低电平/高低频光信号发生改变、
1 -> 0
0 -> 1
校验和的形成
UDP 的校验和使用了 CRC 方式来进行校验 (循环冗余校验),把每个字节(除了校验和位置的部分
之外),都当做整数进行累加,溢出也没关系继续加,最终得到结果crc 校验和传输到对端,如果数
据出现错误了, 对端再次计算的校验和就会和第一个校验和不一样了
校验和的作用
发送之前先计算一个校验和,把真个数据包的数据都代入,把数据和校验和一起发送给对端,对于
接收方收到之后重新计算一下校验和,和收到的校验和进行对比 (UDP发现校验和不一致, 就会直
接丢弃)
补充
两个原始数据相同, 使用相同的校验和算法, 得到的校验和也是相同的 [ok]
如果两个校验和相同, 原始数据一定也相同 [可能存在变数]
例如前一个字节出现 bit 翻转, 刚好小了1后一个字节也出现 bit 翻转,刚好大了1最终加到一起校验
和是一样的
UDP使用注意事项
我们注意到UDP协议首部中有一个16位的最大长度也就是说一个UDP能传输的数据最大长度是
64KB(包含UDP首部),然而64KB在当今的互联网环境下是一个非常小的数字,如果我们需要传输
的数据超过64KB,就需要在应用层手动的分包, 多次发送, 并在接收端手动拼装;
TCP协议
TCP协议的特点:有连接,面向字节流,可靠传输,全双工
TCP协议段格式

16位源端口号和16位目的端口号
传输层的核心内容
4位首部长度
4bit,选项的存在导致TCP的报头的长度是可变的
保留(6位)
TCP的设计者考虑到UDP的问题,所以在TCP的报头中预留了一些"保留位"
标志位
TCP最核心的6个标志位
16位校验和
用来检验数据是否出现错误的
TCP的核心机制
核心机制一: 确认应答
保证可靠性的一个关键前提, 是发送方知道自己的数据是否被对方收到.
需要对方给返回一个 "应答报文" (acknowledge, ack), 发送方知道应答报文, 就可以确认对方是收到了
标志位中的ACK就是确认收到的应答报文

确认应答机制

数据排序
面对海量数据,数据到来的先后顺序可能不一样,可能出现先发后到,后到先发的情形。数据发来
的先后顺序可能会对返回结果有影响,为了解决这种影响,TCP的处理方案是给传输的数据进行编
号

这样数据就会按照先后顺序进行处理

TCP 是面向字节流的,其实在编号的时候不是按照1条,2条这样的方式来编的,而是按照 "字节"
来编号的,每个字节都分配一个编号,编号是连续递增的

对于32位序号:一个 TCP 的载荷是多个字节构成的,序号字段填写载荷部分的第一个字节的序号,然后连续递增加
对于32位确认序号:把收到的数据载荷的最后一个字节序号+1,填写到确认序号中

确认序号的含义
1)< 1001的数据都已经确认收到了
- 接下来你要从1001开始发送
引入数据排序之后,TCP在处理后发先至的情况时,能确保应用程序通过 socket api 读到的数据顺
序是正确的,即使出现后发先至tcp 也可以处理掉,确保代码里读到的数据和发送方写入的数据顺
序一致
TCP 在接收方这里会安排 "接收缓冲区" (内存, 操作系统内核里),通过网卡读到的数据,先放到接
收缓冲区中后续代码里调用 read 也是从接受缓冲区来读的,根据序号来排序,序号小的在前面大
的在后面确保前面的数据已经到了, 然后 read 才能结束阻塞,如果是后面的数据先到,read 继续
阻塞,不会读取到数据

核心机制二:超时重传
超时重传是针对TCP可靠传输中出现丢包情况做出的处理
为什么会出现丢包情况?
数据包经过某个路由器或者交换机转发的时候,该路由器/交换机已经非常繁忙了,导致当前需要
转发的数据量超出路由器/交换机的转发能力上限,导致数据缓存区满了,只能将包丢弃了
丢包在传输中表现

当A向B发送数据,达到等待时间的上限还没有收到 ack,A 就认为传输中发生丢包了
- A -> B 发的数据丢了
- B -> A 返回的 ack 丢了
引入超时时间来判定是否丢包,TCP 中判定超时的时间阈值不是固定数值是动态改变的
假设当前 A -> B 发送数据, 丢包的超时时间阈值为 T,当 A 给B传输发生超时之后,就会延长这个
时间阈值但不是无休止的, 超时次数达到一定程度/等待时间达到一定程度就认为网络出现严重故障,
放弃这一次传输
对于是丢包还是ACK丢失,发送端无法区分


对于丢失ACK的情况
如果 tcp 不处理, 可能会使应用层读到两次一样的数据,tcp 会在内部进行去重操作,就可以根据序
号在接受缓冲区中找一下。如果存在,就直接丢弃;如果不存在,才放进去
TCP协议最核心的两个机制 => 保证了TCP能够进行可靠传输
核心机制三:三次握手和四次挥手
三次握手是抽象的逻辑上的连接,通信双方各自保存对端的信息,用来连接管理,建立连接,断开
连接
建立连接

synchronized在这里的意思是同步的,在加锁中是互斥的意思
在TCP中的同步指的是数据上的同步,告诉通信对方将要建立连接
这里的 syn 和 ack都是内核负责的,和用户代码无关,可以保证是同一时机,同时这里的syn和ack
能同时发送给客户端,这样的合并操作能够有效提高传输的效率
连接管理
在正常情况下,TCP要经过三次握手建立连接,四次挥手断开连接

三次握手的意义
-
投石问路, 确认当前通信路径是否畅通.(网络通畅是可靠传输的前提条件)
-
协商参数, 通信双方共同确认一些通信中的必备参数数值.
3.三次握手构成中可以协商一些关键信息,TCP要协商同行过程中序号从几开始,一般不会从0开
始,并且两次链接初始序号都是不同的(往往差别会很大)
四次挥手
通信双方各自给对方发FIN,标识即将删除对端信息
四次挥手是在程序即将结束的时候做出的操作

ACK与FIN的返回时间不一定相同,ACK由操作系统的内核返回,FIN由代码里调用socket close方
法触发),由于二者的触发时机不同故不能合并
三次握手, 一定是客户端主动发起 syn (第一次握手, 一定是客户端开头的)
四次挥手, 客户端和服务器, 都可以主动发起 FIN (就看是谁先调用 close)

TIME_WAIT给最后一个 ACK 丢包行为, 做一个托底
(不能用 客户端, 服务器 这样的词来描述)
谁是主动发起 FIN 的一方, 就会进入到 TIME_WAIT
谁是被动发起 FIN 的一方, 就会进入 CLOSE_WAIT
丢包情况
网络传输中随时会丢包,三次握手和四次挥手都一样会丢包
如果第一个 FIN 丢了, A 就无法再规定时间内拿到ACK于是 A 重新发送 FIN,如果是第一个 ACK
丢了,同上
如果是第二个 FIN 丢了呢, B 也再次重传就可以了,在第二个 FIN 到达 A 之前,A 这里的连接肯定
是存在的,就能够及时的处理 ACK,当A这边收到FIN之后不能立即释放连接,而是要等待一下,
要等一下对方是否可能要重新传FIN,因为当最后一个ACK丢包,B又会重传FIN

要等多久合适?
等待时间一般设为2*MSL(网络上任何两个传输节点过程中消耗的最大时间),通常这个时间会配
置成60s
超时重传的时间阈值是ms级别
四次挥手的异常情况
当服务器就始终不调用 close
站在 A 的视角,此时A 给B已经把 FIN 发了很久了,B也没有进行后续的挥手操作,A 就会主动释
放连接 (也就是把 B 的核心信息删了)
B 这边由于代码逻辑都有 bug,这里的连接暂时存在(还会保存对方的信息,此时也没法进行正常
的数据通信了)
核心特性四:滑动窗口
对每一个发送的数据段,都要给一个ACK确认应答,收到ACK后再发送下 一个数据段,这样做有
一个比较大的缺点就是性能较差,尤其是数据往返的时间较长的时候

既然这样一发一收的方式性能较低,那么我们一次发送多条数据就可以大的提高性能(其实是将多
个段的等待时间重叠在一起了).
批量传输

前几个数据包都是不等待的,直接往后发,发到一定量(窗口大小)之后再等待,用一份时间等多
组ACK(把多组等待ack的时间重叠成一份),对于下一组数据的发送是收到一个ack就发下一条

如果这里的2001ack比1001ack先到,窗口直接往后走两个格子就可以了,2001ack能够涵盖到
1001的含义
确认序号的含义:该序号之前的数据都确认收到了
窗口越大,批量发的数据越多效率就越高,但是窗口也不能无限大,太大也会影响到可靠性,滑动
窗口是在可靠传输的基础上提高效率。
引入可靠性会使效率产生折损,引入滑动窗口是要让折损更小,不可能效率比UDP这种还高
滑动窗口的丢包情况
情况一:数据包已经抵达,ACK被丢了

这种情况不用做任何处理,后一个ack能够涵盖前一个ack的含义
情况二: 数据包就直接丢了

2001-3000的数据包发送过来但不能直接返回3001,虽然收到的是2001-3000,但是由于1001-
2000丢包了,接收方仍然在索要1001的数据
1001-2000重传成功之后,此时的确认序号就是7001因为刚才2001-7000这些数据都收到了就差
1001-2000了,通过重传一下就把缺失的拼图补上了,补上之后继续从 7001 往后传输就可以了

每个数据都是有序的,可以根据序号准确计算出数据应该放在哪个位置,前面需要空多少
本来就已经预留了位置了,此处就直接把后来收到的1001-2000填到空位上就行了
快速重传
只是谁丢了重传谁其他已经收到的数据无需重传,整个重传过程速度很快的(滑动窗口下的, 超时重
传的变种操作)
超时重传和快速重传区别
超时重传传输的数据量少,没有构成滑动窗口批量传输的形式 => 超时重传
快速重传传输数据量多,形成滑动窗口 => 快速重传~
核心特性五:流量控制
接收端处理数据的速度是有限的,如果发送端发的太快,导致接收端的缓冲区被打满,这个时候如
果发送端继续发送,就会造成丢包,继而引起丢包重传等等一系列连锁反应
应用程序需要从接收缓冲区中读取数据,就相当于放水,读一个字节这个字节就可以从接收缓冲区
删除

流量控制可以让接收方根据自身处理数据的速度反馈给发送方,限制发送方发送的速度,在 ack
中,依赖一个特殊的属性"窗口大小"

窗口探测

核心机制六:拥塞控制
虽然TCP有了滑动窗口这个大杀器,能够高效可靠的发送大量的数据。但是如果在刚开始阶段就发
送大量的数据仍然可能引发问题。当网络状态不佳的情况发送大量数据,即使在滑动窗口大小可接
受范围里,仍然会很容易出现数据丢失的情况,引入拥塞控制来调节传输状态
拥塞控制是依据传输链路的转发能力,进行限制的;流量控制是依据接收方处理能力,进行限制的
(根据接受缓冲区空余空间, 来定量衡量)
TCP引入慢启动机制,先发少量的数据探探路摸清当前的网络拥堵状态再决定按照多大的速度传输
数据,类似于:
先按照小的窗口(小的速度) 先发着,如果发的时候很顺利不丢包,加大速度,出现丢包减小速度,
又不丢包了继续加大速度,又丢包了继续减小速度。
下图是传输轮次与拥塞窗口的关系

随着阈值不断变化,后面慢启动的起点上升
拥塞控制和流量控制都能限制发送方的窗口大小,谁在传输过程中有主导作用是看谁小
核心机制七:延时应答
默认情况下接收方都是在收到数据报第一时间就返回 ack,但是可以通过延时返回 ack 的方式来提
高效率

那么所有的包都可以延迟应答么? 肯定也不是
1.数量限制: 每隔N个包就应答一次
不会因为ack少了影响可靠性,确认序号后一个能够涵盖前一个
2.时间限制: 超过最大延迟时间就应答一次
对于上面两种延时应答的方式是综合的
传输的数据密集就按第一个
传输的数据稀疏就按第二个
核心机制八:捎带应答
TCP 已经有了延时应答了,基于延时应答引入 "捎带应答",返回业务数据的时候顺便把上次的 ack
给带回去

核心机制九:面向字节流
粘包问题
粘的是应用层数据包,通过字节流方式传输,很容易混淆包和包之间的边界,从而接受方无法去区
分哪里到哪里是一个完整的应用层数据包
上述问题在 tcp 的层次上无解,需要站在应用层解决,定义好应用层协议,明确包之间的边界
1.约定包和包之间的分隔符 (包的结束标记)
echo server 采用的办法,约定 \n 作为结束标记
直接往后read,读到\n,就认为读到一个完整数据包
2.约定包的长度
比如约定每个包开头 4 个字节, 表示数据包一共多长

先读一个字节得到长度,再根据长度决定接下来读多少
核心机制十:异常情况处理
TCP在通信过程中存在特殊情况
1.某个进程崩溃了
进程崩溃和主动退出没有本质区别,进程释放 => 回收文件描述符表的每个资源 => 调用 socket 的 close
close会FIN触发四次挥手,进程虽然没了但是 TCP 的连接信息还存在,此时四次挥手还是可以正
常进行的
2.主机关机了
正常流程的关机本质上还是会先杀死所用的用户进程,关机也需要一定的时间。如果一定时间内,
四次挥手挥完了就和正常一样了,但如果没有挥完呢?

3.主机掉电了
接收方掉电

A 突然掉电了,B 后续发来的数据都没有ACK了,对于 B 触发超时重传不能解决问题,重传达到一
定次数就会触发 "重置 TCP 连接",B 主动发送一个 复位报文
此处的RST同样没有ACK,B就只能单方面释放连接了
发送方突然掉点了

B 突然发现A 没有声音了,此时B区分不了 A 是挂了,还是暂时休息一会,B 只能继续等 (不会无
限等),B 等待一定时间之后就会给 A 传输一个特殊的报文,"心跳包"不携带业务数据(载荷)只是为
了触发 ACK
心跳包类似于窗口探试包
1.周期性的
2.没有心跳的就认为对方挂了
如果对方有心跳继续正常等待,如果没心跳就只能通过 rst 尝试,还是不行就只能单方面释放连接
保活机制
分布式系统中,心跳包的思想方法非常广泛使用的(TCP 的心跳周期太长了,分钟级别的),虽然
TCP 内置了心跳包, 实际开发中通常还是会在应用层重新实现心跳包效果,现在通常希望秒级甚至
毫秒级就能发现对端是否正常存活从而触发一些后续的操作
4.网线断了

站在 A 的视角就是和刚才上面 "接收方掉电" 是一样的情况;站在B 的视角就和刚才上面 "发送方掉
电" 是一样的情况
最终都是能够释放连接资源的
TCP和UDP对比
TCP可靠传输(大部分场景下都会优先使用TCP),HTTP,浏览器/app访问服务器常用
UDP效率更高(对于性能要求高,可靠性要求不高的场景下使用UDP),但存在长度问题
网络层
在复杂的网络环境中确定一个合适的路径
IP协议
基本概念
- 主机: 配有IP地址, 但是不进行路由控制的设备;
- 路由器: 即配有IP地址, 又能进行路由控制;
- 节点: 主机和路由器的统称;
协议头格式
IP 协议/网络层做的工作主要是两个:
- 地址管理 使用 IP 地址, 这样的概念, 标识网络上的某个设备的位置
- 路由选择 在两个通信的节点之间, 规划出一个合理的路径

4位版本

主要指的是IPv4和IPv6
4位首部长度

IP协议的报头,也是可以变长的
8位服务类型

决定了IP协议的工作方式,用来切换工作状态
16位总长度

一个IP数据报=报头+载荷的长度
IP协议内置了拆包组包功能,当IP携带一个比较大的TCP数据报,IP协议就会自定拆成多个,通过
多个IP数据报共同传输一个TCP数据报
16位标识+3位标志+13位偏移

8位生存时间

一个 IP 数据报能够在网络上传输的最大时间,单位是 "次数",IP 数据报每次经过一个路由器转发
一次TTL 的值就 - 1,TTL 减到 0就说明包到不了就要被丢弃掉

初始TTL是64,中间经过了9次路由器的转发,到达了bilibili的服务器
但会出现明明地址是对的,但通过64次转发下来,数据到达不了对方?
- 64可能太小,要设置成128

- 其实网络中有一个"六度空间"这样的理论,两个设备之间不需要那么多次转发,只需要几次就足
够了
8位协议

标识传输层使用哪种协议。分用的时候IP 协议解析 IP 数据报的时候,拿到载荷交给上层处理此处
8 位协议编号就能起到区分效果
传输层到应用层 => 端口号
网络层到传输层 => 8 位协议
数据链路层到网络层 => 也有一个类似的协议编号的
16位首部检验和

载荷部分的自行校验
32位源IP和目的IP地址

IP协议最关键的部分
IP 地址本质上是通过 32 位的整数来表示的,但由于 32 位整数不方便阅读通常会把IP写作点分十
进制的表示方式,用 三个点分出四个部分

IP分配
作为互联网非常重要的部分,IP出现不够用的情况怎么办?
1.动态分配
上网再分配,不上网就不分配。有所缓解但不能根本上解决问题
2.NAT机制,网络地址转换(当前网络世界的最主要的方式)
把所有的IP分成两个大类
(1)公网IP/外网IP
公网IP是唯一的
(2)私网IP/内网IP
私网IP在不同的局域网中可以重复,例如192.168.137.1,在同一个局域网中不会有人重复,但在
不同局域网中可能会出现重复
NAT 机制就可以用一个 外网IP对应到一系列的内网的设备
一个设备有一个独立的局域网 IP (允许重复)
但是多个设备共用同一个外网 IP (不允许重复)
NAT背景下,网络通信是如何进行的?
(1)同一个局域网下,设备A访问设备B
由于IP本身不允许重复,自然不受任何影响,NAT不起到作用。
(2)公网设备A访问公网设备B
由于公网IP本身也不重复,也不受到影响,NAT不起作用。
(3)不同局域网,设备A访问设备B不允许的
NAT机制禁止这样的访问方式
(4)局域网设备A访问公网设备B
网络地址映射,当路由器触发NAT地址替换的时候,自身维护一个"哈希表"结构记录替换的映射关
系
(5)公网设备A尝试访问局域网设备B,这种情况是不允许的,但在内网穿透的情况下可以使用
3.IPv6
IPv4 是使用 4 个字节作为 IP 地址,IPv6 是使用 16 个字节作为 IP 地址
但IPv6和IPv4是不兼容的,升级IPv6需要更换新的设备
IP地址的其他规则
网段划分
IP地址分为两个部分, 网络号和主机号
网络号: 保证相互连接的两个网段具有不同的标识;
主机号: 同一网段内,主机之间具有相同的网络号,但是必须有不同的主机号
把一个IP地址分成两个部分,前半部分称为"网络号",后半部分称为"主机号"

同一个局域网中,网络号必须相同主机号必须不同;两个相邻的局域网中,网络号必须不同主
机号无限制
相邻局域网
两个红框就是一个想来局域网,这两设备不能有一样的网络号,如果出现两个相同的网络号就无法
上网了

路由器
路由器有两个网络端口,一个连接居家设备,另一个是连接提供服务方的

一个路由器有两个IP,这两个IP就在两个不同的局域网中,路由器就相当于把这两个局域网连接到
一起了
子网掩码

255事实上是二进制的1111 1111
子网掩码也是一个32位的整数,左半部分都是1右半部分都是0,不会出现01交错的情况,1的部分
就表示了哪些bit位是网络号。
家用网络一般都是255.255.255.0也可以简写作192.168.100.98/24
特殊的IP地址
- 将IP地址中的主机地址全部设为0就成为了网络号,代表这个局域网
- 将IP地址中的主机地址全部设为1就成为了广播地址,用于给同一个链路中相互连接的所有主机发 送数据包,例如:192.168.100.255就是一个广播地址
- 127.*的IP地址用于本机环回(loop back)测试,通常是127.0.0.1。环回IP,无论你本机真实的IP是多少,都可以写作127.0.0.1作为代表
- 主机号为1的IP通常会设为网关IP,网关是网络的出口/入口
路由选择
IP协议中的第二个要点。路由选择是通过IP协议进行数据传发的过程
IP数据包的传输过程也和问路一样
- 当IP数据包到达路由器时,路由器会先查看目的IP
- 路由器决定这个数据包是能直接发送给目标主机还是需要发送给下一个路由器
- 依次反复一直到达目标IP地址
这里的下一个路由器是指上一级路由器,越往上涵盖的范围越大

数据链路层
以太网
以太网是数据链路层+物理层的协议,但凡电脑要通过网线的方式上网要走的协议就是以太网
以太网帧格式

此处的地址不是IP地址而是mac地址(物理地址),地址长度是6字节的数据

注意:mac地址是够用的,mac地址就相当于网卡的地址,是唯一的,网卡出厂时就写死了。mac
地址也可以作为一个电脑的身份标识
IP地址和mac地址有啥区别?为啥有了IP还要有mac呢?
其实理论上来说,网络通信中有一组地址就够用了,但最初构建网络层协议的大佬和构建数据链路
层协议的大佬,不是一伙人干脆就全都要。
IP就专门给网络层使用,mac专门给数据链路层使用。程序员日常开发的时候,基本都是和IP打交
道不会涉及到mac,例如:IP是在网络层使用,关注于整个网络路径的转发传输过程;Mac是在数
据链路层使用,关注与转发的细节两个相邻设备之间的转发
IP地址始终时整个通信线路的起点和终点,mac地址只是关注当前一段路,从哪到哪
帧格式详解

ARP不是传输业务数据的而是打辅助的协议,功能是根据 IP 地址得到对应的 mac 地址
网络传输过程中,网络这一层转发是要根据 IP 的;数据链路层这一层,是要根据 mac的
写代码的时候,填写的肯定是 IP 地址,路由器也是根据 IP 地址查路由表,根据路由表得到接下来
从哪个网口转发,此时就往往需要根据下一个节点的 ip找到对应的 mac,才能填写以太网数据帧
DNS
DNS是一整套从域名映射到IP的系统,可以认为是一个应用层协议也可以认为是一套系统。
域名解析系统
网络上的服务器都是有 IP 地址的,域名:是一串单词,计算机会自动把这串单词翻译成 IP 地址

最初DNS是通过hosts文件实现映射的,但hosts文件维护太复杂了,于是把 hosts 文件中的内容提
取出来单独放到一个服务器上,这样的服务器就称为 DNS 服务器

用户的电脑访问某个网站的时候就会先查询 DNS 服务器,把域名对应的 ip 拿到再真正访问服务器
如果有大量数据同时访问DNS服务器,DNS服务器是如何应对的?
1.缓存
电脑不会每次请求服务器都触发DNS请求,每进行一次DNS之后就把IP记录下来了,下次再访问
同一个地址就不需要重新访问DNS
2.增加DNS的服务器
存储原始数据的DNS服务器称为"DNS根服务器",各种运营商可以搭建"DNS镜像服务器"