8.计算机网络
一、计算机网络基础
1.1 网络分层模型
1.1.1 OSI七层模型是什么?
OSI 七层模型 是国际标准化组织提出一个网络分层模型,其大体结构以及每一层提供的功能如下图所示:

OSI 的七层体系结构概念清楚,理论也很完整,但是它比较复杂而且不实用,而且有些功能在多个层中重复出现。
1.1.2 TCP/IP四层模型是什么?
TCP/IP 四层模型 是目前被广泛采用的一种模型,我们可以将 TCP / IP 模型看作是 OSI 七层模型的精简版本,由以下 4 层组成:
- 应用层
- 传输层
- 网络层
- 网络接口层

1.1.3 为什么网络要分层?
复杂的系统需要分层,因为每一层都需要专注于一类事情。网络分层的原因也是一样,每一层只专注于做一类事情。
各层之间相互独立:各层之间相互独立,各层之间不需要关心其他层是如何实现的,只需要知道自己如何调用下层提供好的功能就可以了(可以简单理解为接口调用)。这个和我们对开发时系统进行分层是一个道理。
提高了整体灵活性 :每一层都可以使用最适合的技术来实现,你只需要保证你提供的功能以及暴露的接口的规则没有改变就行了。这个和我们平时开发系统的时候要求的高内聚、低耦合的原则也是可以对应上的。
大问题化小 : 分层可以将复杂的网络问题分解为许多比较小的、界线比较清晰简单的小问题来处理和解决。这样使得复杂的计算机网络系统变得易于设计,实现和标准化。 这个和我们平时开发的时候,一般会将系统功能分解,然后将复杂的问题分解为容易理解的更小的问题是相对应的,这些较小的问题具有更好的边界(目标和接口)定义。
1.2 常用网络协议
1.2.1 应用层有哪些常用的协议?

1.2.2 传输层有哪些常用的协议?

1.2.3 网络层有哪些常用的协议?

二、HTTP
2.1 HTTP组成
每条HTTP报文都包含一个来自客户端的请求,或者一条来自服务器的响应。HTTP报文分两类:请求报文和响应报文。不管是请求报文还是响应报文每条HTTP报文是由3部分组成,分别是:起始行、首部、主体。
2.1.1 起始行
请求行、响应行
请求行:请求报文请求服务器对资源进行一些操作。通俗讲就是客户端想服务器发起请求的请求命令。包含了
方法:如:get、post等
请求URL:如:/src/test.pdf
版本号:版本号是指HTTP/1.1或HTTP/2.0等
响应行:响应报文承载了状态信息和操作产生的所有结果数据,将其返回给客户端。包含了响应报文使用的HTTP版本,状态码(如:200、404等),以及描述操作状态的文本形式的原因短语。
2.1.2 首部
首部分类:通用首部(既可以出现在请求报文中,也可以出现在响应报文中)、请求首部、响应首部、实体首部(描述主题的长度和内容,或者资源本身)、扩展首部。
在这里简单列一些常见的首部
通用首部:
- cache-control:用于传输对象的缓存信息;
- Date: 用来给出报文创建的日期和时间。
请求首部:
- Accept:客户端用Accept首部来通知服务器可以接受哪些媒体类型。例如:Accept: text/*, image/、Accept: text/, image/gif, image/jpeg; q=1等
- Authorization:客户端用来向服务器回应自己的身体的验证信息。
- From:用来说明请求来自何方。
响应首部:
- Age:告诉接受端响应已产生了多长时间。
- Allow:用于通知客户端可以对特定资源使用哪些HTTP方法。例如:Allow: GET, HEAD
实体首部:
- Content-Encoding:用于说明是否对某对象进行过编码。
- Content-Language:用来告诉对方,想要理解对象的客户端,应该理解哪种自然语言。
- Content-Length:用来说明实体主体部分的长度和尺寸。
2.2 从输入URL到页面展示期间到底发生了什么?
这个问题非常重要,基本包含了整个计算机网络的知识!能展开问的东西很多很多。
- 输入正确的url网址;
- DNS解析域名的IP地址;(什么是DNS?DNS解析IP地址的具体过程是什么?)
- 建立TCP连接,也就是三次握手;(三次握手的具体过程是什么?)
- 客户端发送HTTP/HTTPS请求;(HTTP和HTTPS的区别是什么?Post和Get的区别是什么?)
- 服务器处理请求并返回HTTP报文;(常见的状态码有哪些?分别代表什么含义?)
- 浏览器解析渲染页面;
- HTTP请求结束,断开TCP连接,也即四次挥手。(四次挥手的具体过程是什么?为什么TIME_WAIT之后需要等待2MSL?)
2.2.1 打开一个网页,整个过程中会使用到哪些协议?
- DNS:获取域名对应的IP
- TCP:与服务器建立TCP连接
- IP:建立TCP协议时,需要发送数据,发送数据在网络层使用IP协议
- OSPF:IP数据包在路由器之间,路由选择使用OSPF协议
- ARP:路由器与服务器通信时,需要将IP地址转换为MAC地址
- HTTP:在TCP建立连接后,使用HTTP协议访问网页
2.3 HTTP状态码有哪些?

1xx
类状态码属于提示信息,是协议处理中的一种中间状态,实际用到的比较少。
- 「100 Continue」:表示正常,客户端可以继续发送请求。
- 「101 Switch Protocols」: 切换协议,服务器根据客户端的请求切换协议。
2xx
类状态码表示服务器成功处理了客户端的请求,也是我们最愿意看到的状态。
- 「200 OK」是最常见的成功状态码,表示一切正常。如果是非
HEAD
请求,服务器返回的响应头都会有 body 数据。 - 「204 No Content」也是常见的成功状态码,与 200 OK 基本相同,但响应头没有 body 数据。
- 「206 Partial Content」是应用于 HTTP 分块下载或断点续传,表示响应返回的 body 数据并不是资源的全部,而是其中的一部分,也是服务器处理成功的状态。
3xx
类状态码表示客户端请求的资源发生了变动,需要客户端用新的 URL 重新发送请求获取资源,也就是重定向。
- 「301 Moved Permanently」表示永久重定向,说明请求的资源已经不存在了,需改用新的 URL 再次访问。
- 「302 Found」表示临时重定向,说明请求的资源还在,但暂时需要用另一个 URL 来访问。
注:301 和 302 都会在响应头里使用字段 Location
,指明后续要跳转的 URL,浏览器会自动重定向新的 URL。
- 「304 Not Modified」不具有跳转的含义,表示资源未修改,重定向已存在的缓冲文件,也称缓存重定向,也就是告诉客户端可以继续使用缓存资源,用于缓存控制。
4xx
类状态码表示客户端发送的报文有误,服务器无法处理,也就是错误码的含义。
- 「400 Bad Request」表示客户端请求的报文有错误,但只是个笼统的错误。
- 「403 Forbidden」表示服务器禁止访问资源,并不是客户端的请求出错。
- 「404 Not Found」表示请求的资源在服务器上不存在或未找到,所以无法提供给客户端。
5xx
类状态码表示客户端请求报文正确,但是服务器处理时内部发生了错误,属于服务器端的错误码。
- 「500 Internal Server Error」与 400 类型,是个笼统通用的错误码,服务器发生了什么错误,我们并不知道。
- 「501 Not Implemented」表示客户端请求的功能还不支持,类似“即将开业,敬请期待”的意思。
- 「502 Bad Gateway」通常是服务器作为网关或代理时返回的错误码,表示服务器自身工作正常,访问后端服务器发生了错误。
- 「503 Service Unavailable」表示服务器当前很忙,暂时无法响应客户端,类似“网络服务正忙,请稍后重试”的意思。
- 「504 Gateway Time-out」充当网关或代理的服务器,未及时从远端服务器获取请求。
2.4 HTTP和HTTPS有什么区别?
- 端口号:HTTP默认端口号是80,HTTPS默认端口号是443。
- URL前缀:HTTP的前缀是
http://
,HTTPS的前缀是https://
。 - 安全性和资源消耗:HTTP协议运行在TCP之上,所有的传输内容都是明文,客户端和服务端都无法验证对方身份。HTTPS是运行在SSL/TLS之上,所有的传输内容都是进过加密,加密采用对称加密,但对称加密的密钥用服务器方的整数进行非对称加密。所以说HTTP的安全性没有HTTPS高,但是HTTPS比HTTP消耗更多的服务器资源。
- 搜索引擎优化:搜索引擎通常会更青睐使用HTTPS协议的网站,因为HTTPS能提供更高的安全性和用户隐私保护。
2.4.1 HTTPS加密的过程

- 客户端将自己支持的加密算法发给服务器;
- 服务器选择一套客户端支持的加密算法,以证书形式返还给客户端;
- 客户端解析证书并验证证书的合法性,生成对称加密的密钥,也即客户端密钥,用服务器的公钥对客户端的密钥进行非对称加密;
- 客户端将加密好的密文发送给服务器;
- 服务器接收到客户端的密文后,会用自己的私钥对其进行解密,解密之后的明文就是客户端的密钥,然后使用客户端的密钥对要传递的数据进行对称加密。
2.5 HTTP/1.0和HTTP/1.1有什么区别?

- 连接方式:1.0为短连接,1.1支持长连接。
- 状态响应码:1.1中加入了大量新的状态码,比如说
409 (Conflict)
——请求与当前资源的规定冲突,410 (Gone)
——资源已被永久转移等。 - 缓存机制:1.0中主要使用 Header 里的
If-Modified-Since
,Expires
来做为缓存判断的标准,1.1中引入更多的缓存控制策略。 - 带宽:1.0中存在浪费带宽的现象,比如说客户端只需要某个对象的一部分,而服务器将整个对象送过来了,还不支持断点续传的功能。1.1中在请求头中引入了range头域,允许只请求资源的某一部分。
- Host头处理:1.1引入了Host头字段,允许在同一IP地址上托管多个域名,从而支持虚拟主机的功能。而1.0没有该功能。
2.5.1 解释一下什么是长连接和短连接?
- 短连接:client与server通过三次握手建立连接,client发送请求消息,server返回响应,一次连接就完成了。
- 长连接:client向server发起连接,server接受client连接,双方建立连接。client与server完成一次读写之后,它们之间的连接并不会主动关闭,后续的读写操作会继续使用这个连接。
2.6 HTTP/1.1和HTTP/2.0有什么区别?

- IO多路复用:2.0在同一连接上可以同时传输多个请求和响应。而1.1使用串行方式,每个请求和响应都需要独立的连接。这使得2.0在处理多个请求时更高效,减少了网络延迟、提高了性能。
- 二进制帧:2.0使用二进制帧进行数据传输,1.1使用文本格式报文。二进制帧更紧凑、高效,减少了传输的数据量和带宽消耗。
- 头部压缩:1.1支持Body压缩,Header不支持压缩。2.0支持对Header的压缩,减少了网络开销。
- 服务器推送:2.0支持服务器推送,可以在客户端请求一个资源时,将其他相关资源一并推送给客户端,从而减少客户端的请求次数和延迟。而1.1需要自己发送请求获取相关资源。
2.7 HTTP/2.0和HTTP/3.0有什么区别?
)
- 队头阻塞:2.0多请求复用一个TCP,一旦发生丢包就会阻塞所有HTTP请求。而3.0使用QUIC一定程度上解决了队头阻塞,一个连接建立多个不同的数据流,数据流之间互不影响。
- 错误恢复:3.0有更好的错误恢复机制,当出现丢包、延迟等问题时,可以更快进行回复和重传。而2.0依赖于TCP的错误恢复机制。
- 安全性:两者都支持加密通信,但是实现方式不同,2.0使用TLS进行加密,而3.0基于QUIC协议,包含了内置的加密和身份验证机制,安全性更强。
2.8 HTTP是不保存状态的协议,那么如何保存用户状态?
使用Session机制,Session的主要作用就是通过服务端记录用户状态。最典型的场景就是购物车,当需要向购物车中添加商品时,系统不知道是哪个用户操作的,因为HTTP协议是无状态的,所以服务器给特定的用户创建特定的Session之后,就可以标识这个用户并跟踪这个用户了。
在服务端保存Session的方式很多,最常用的就是内存和数据库(比如Redis)。
2.8.1 Session存在服务端,那如何实现Session的跟踪?
大多数情况下,通过Cookie中附加一个Session ID来进行跟踪。
2.8.2 如果Cookie被禁用怎么办?
最常用的方法就是利用URL重写把Session ID直接附加在URL路径的后面。
2.9 常见概念的区别
2.9.1 URI和URL的区别是什么?
- URI(Uniform Resource Identifier):是统一资源标志符,可以唯一标识一个资源。
- URL(Uniform Resource Locator):是统一资源定位符,可以提供该资源的路径。它是一种具体的URI,即 URL 可以用来标识一个资源,而且还指明了如何 locate 这个资源。
URI 的作用像身份证号一样,URL 的作用更像家庭住址一样。URL 是一种具体的 URI,它不仅唯一标识资源,而且还提供了定位该资源的信息。
2.9.2 Cookie和Session有什么区别?
- 存储位置不同:Cookie存储在客户端的浏览器中,而Session存储在服务器。
- 存储内容不同:Cookie中只能存储字符串类型的数据,而Session可以存储任何Java对象。
- 安全性不同:Cookie中存储的信息可以被客户端查看和修改,而Session存储在服务器上,客户端无法查看和修改。
- 生命周期不同:Cookie可以设置过期时间,而Session默认在客户端关闭浏览器后就会失效。
- 存储容量不同:Cookie大小有限制,而Session存储容量较大,一般可以存储几MB的数据。
Cookie一般只能存储一些简单的用户信息,比如用户名、密码等;
Session用于在服务器存储一些复杂的对象信息,比如购物车、用户登录信息等。
2.9.3 Get和Post有什么区别?
GET 的语义是从服务器获取指定的资源,这个资源可以是静态的文本、页面、图片视频等。GET 请求的参数位置一般是写在 URL 中,URL 规定只能支持 ASCII,所以 GET 请求的参数只允许 ASCII 字符 ,而且浏览器会对 URL 的长度有限制(HTTP协议本身对 URL长度并没有做任何规定)。

POST 的语义是根据请求负荷(报文body)对指定的资源做出处理,具体的处理方式视资源类型而不同。POST 请求携带数据的位置一般是写在报文 body 中,body 中的数据可以是任意格式的数据,只要客户端与服务端协商好即可,而且浏览器不会对 body 大小做限制。

主要区别如下:
- 参数位置:Get请求的参数以查询字符串形式写在URL中,而Post请求的参数出现在HTTP请求的消息体中。
- 安全性:Get请求的参数暴露在URL中,所以可以被浏览器缓存、历史记录等保存,存在安全风险,而Post的请求参数在消息体中,相对安全。
- 参数大小:Get请求因为在URL中,有长度限制,取决于浏览器和服务器的限制,而Post的请求没有长度限制。
- 编码方式:Get请求的参数默认使用URL编码,在传递非ASCⅡ字符时需要进行编码,而Post请求支持多种编码方式。
- 幂等性:Get请求是幂等的,即多次请求返回的结果是一致的;而Post请求不一定是幂等的,因为可能会对服务器状态进行修改。
总结:Get请求适合用于获取服务器资源(适合读),Post请求适合用于提交数据(适合写)。
2.10 HTTP的缓存技术了解吗?
2.10.1 HTTP为什么要用缓存技术?
当客户端向服务器请求资源时,会先去查浏览器缓存,如果缓存中有要请求资源,就可以直接从浏览器缓存中提取而不用再从原始服务器中请求这个资源。
优点:
- 缓解服务器压力;
- 降低客户端获取资源的延迟:缓存服务器在地理位置上也有可能比源服务器来得近,例如浏览器缓存和服务器缓存。
HTTP缓存技术有两种实现方式,分别是强制缓存和协商缓存。
2.10.2 强制缓存
强缓存指的是只要浏览器判断缓存没有过期,则直接使用浏览器的本地缓存,决定是否使用缓存的主动权在于浏览器这边。
强缓存是利用下面这两个 HTTP 响应头部(Response Header)字段实现的,它们都用来表示资源在客户端缓存的有效期:
Cache-Control
, 是一个相对时间;Expires
,是一个绝对时间;
2.10.3 协商缓存
协商缓存就是与服务端协商之后,通过协商结果来判断是否使用本地缓存。
协商缓存可以基于两种头部来实现。
第一种:请求头部中的 If-Modified-Since
字段与响应头部中的 Last-Modified
字段实现,这两个字段的意思是:
- 响应头部中的
Last-Modified
:标示这个响应资源的最后修改时间; - 请求头部中的
If-Modified-Since
:当资源过期了,发现响应头中具有 Last-Modified 声明,则再次发起请求的时候带上 Last-Modified 的时间,服务器收到请求后发现有 If-Modified-Since 则与被请求资源的最后修改时间进行对比(Last-Modified),如果最后修改时间较新(大),说明资源又被改过,则返回最新资源,HTTP 200 OK;如果最后修改时间较旧(小),说明资源无新修改,响应 HTTP 304 走缓存。
第二种:请求头部中的 If-None-Match
字段与响应头部中的 ETag
字段,这两个字段的意思是:
- 响应头部中
Etag
:唯一标识响应资源; - 请求头部中的
If-None-Match
:当资源过期时,浏览器发现响应头里有 Etag,则再次向服务器发起请求时,会将请求头 If-None-Match 值设置为 Etag 的值。服务器收到请求后进行比对,如果资源没有变化返回 304,如果资源变化了返回 200。
第一种实现方式是基于时间实现的,第二种实现方式是基于一个唯一标识实现的,相对来说后者可以更加准确地判断文件内容是否被修改,避免由于时间篡改导致的不可靠问题。

只有在未命中强制缓存的时候,才会发起协商缓存的请求。
2.11 安全相关问题
2.11.1 对称加密和非对称加密有什么区别?
- 对称加密:使用相同的密钥对数据进行加密和解密。常见的对称加密算法有DES、AES等。优点是加密和解密速度快,缺点是密钥管理不方便,如果密钥被泄露,数据就会变得不安全。
- 非对称加密:使用一对公钥和私钥对数据进行加密和解密。公钥可以自由分发,任何人都可以使用公钥对数据进行加密,但是只有拥有私钥的人才能解密。常见的非对称加密算法有RSA、DSA等。优点是密钥管理方便,缺点是加密和解密速度较慢。
2.11.2 XSS攻击是什么?
XSS攻击指跨站点脚本攻击,指攻击者通过篡改网页,嵌入恶意脚本程序,在用户浏览网页时,控制用户浏览器进行恶意操作的一种攻击方式。
如何防范XSS攻击:
- 前端,服务端,同时需要限制字符串输入的长度。
- 前端,服务端,同时需要对HTML转义处理。将其中的”<”,”>”等特殊字符进行转义编码。 防 XSS 的核心是必须对输入的数据做过滤处理。
2.11.3 CSRF攻击是什么?
CSRF攻击指跨站点请求伪造,指攻击者通过跨站请求,以合法的用户的身份进行非法操作。
可以简单理解为:攻击者盗用你的身份,以你的名义向第三方网站发送恶意请求。CRSF能做的事情包括利用你的身份发邮件,发短信,进行交易转账,甚至盗取账号信息。
如何防范CSRF攻击:
- 安全框架,例如Spring Security。
- Token机制。在HTTP请求中进行Token验证,如果请求中没有Token或者Token内容不正确,则认为CSRF攻击而拒绝该请求。
- 验证码。通常情况下,验证码能够很好的遏制CSRF攻击,但是很多情况下,出于用户体验考虑,验证码只能作为一种辅助手段,而不是最主要的解决方案。
- Referer识别。在HTTP Header中有一个字段Referer,它记录了HTTP请求的来源地址。如果Referer是其他网站,就有可能是CSRF攻击,则拒绝该请求。但是,服务器并非都能取到Referer。很多用户出于隐私保护的考虑,限制了Referer的发送。在某些情况下,浏览器也不会发送Referer,例如HTTPS跳转到HTTP。
三、PING
3.1 PING命令的作用是什么?
PING命令是一种常用的网络诊断工具,经常用来测试网络中主机之间的连通性和网络延迟。
1 | C:\Users\Acer>ping www.baidu.com |
3.2 PING命令的工作原理是什么?
PING 基于网络层的 ICMP(Internet Control Message Protocol,互联网控制报文协议),其主要原理就是通过在网络上发送和接收 ICMP 报文实现的。
ICMP 报文中包含了类型字段,用于标识 ICMP 报文类型。ICMP 报文的类型有很多种,但大致可以分为两类:
- 查询报文类型 :向目标主机发送请求并期望得到响应。
- 差错报文类型 :向源主机发送错误信息,用于报告网络中的错误情况。
PING 用到的 ICMP Echo Request(类型为 8 ) 和 ICMP Echo Reply(类型为 0) 属于查询报文类型 。
- PING 命令会向目标主机发送 ICMP Echo Request。
- 如果两个主机的连通性正常,目标主机会返回一个对应的 ICMP Echo Reply。
三、DNS
3.1 DNS的作用是什么?
DNS是域名管理系统,是当前用户浏览器访问网址之后,使用的第一个重要的协议。
DNS解决的是域名和IP地址的映射问题。
在实际使用中,有一种情况下,浏览器是可以不必动用 DNS 就可以获知域名和 IP 地址的映射的。
浏览器在本地会维护一个hosts
列表,一般来说浏览器要先查看要访问的域名是否在hosts
列表中,如果有的话,直接提取对应的 IP 地址记录就好了。如果本地hosts
列表内没有域名与IP 对应记录的话,那么 就需要用到DNS 。
目前 DNS 的设计采用的是分布式、层次数据库结构,DNS 是应用层协议,基于 UDP 协议之上,端口为 53 。
3.2 DNS服务器有哪些?
- 根DNS服务器:根 DNS 服务器提供 TLD 服务器的 IP 地址。目前世界上只有 13 组根服务器,我国境内目前仍没有根服务器。
- 顶级域DNS服务器(TLD服务器):顶级域是指域名的后缀,比如
com
、org
、net
、edu
等等。顶级域服务器提供权威DNS服务器IP地址。 - 权威DNS服务器:在因特网上具有公共可访问主机的每个组织机构必须提供公共可访问的 DNS 记录,这些记录将这些主机的名字映射为 IP 地址。
- 本地DNS服务器:每个互联网服务提供商都有一个自己本地DNS服务器。当主机发出DNS请求时,该请求被发往本地DNS服务器,起到代理的作用。
3.3 DNS解析的过程是什么样的?
- 客户端首先发出一个DNS请求,问
www.server.com
的IP是啥,并发给本地的DNS服务器(也就是本地客户端的TCP/IP设置中填写的DNS服务器地址)。 - 本地域名服务器收到客户端请求后,如果缓存的表格中能找到这个网址的IP地址,那么就直接返回IP地址;如果没有,则本地DNS会去问它的根域名服务器,这个网址的IP地址。根域名服务器是最高层次的,它不直接用于域名解析,但能指明一条道路。
- 根DNS收到本地DNS请求后,发现网址后置是
.com
,则会告诉本地DNS这个网址归.com
顶级域名服务器管理,并把这个顶级域名服务器的地址给本地DNS。 - 本地DNS收到地址后,去询问顶级域名服务器,然后顶级域名服务器会给
www.server.com
区域的权威DNS服务器地址。 - 本地DNS服务器去询问权威DNS服务器,权威DNS服务器查询到IP地址后,告诉本地DNS。
- 本地DNS再将IP地址告诉客户端,客户端与目标建立连接。
四、TCP和UDP
4.1 TCP和UDP的区别
- 是否面向连接:UDP在传输数据之前不需要先建立连接。TCP在传输数据之前需要先建立连接,传输结束后要释放连接。
- 是否可靠传输:远程主机收到UDP报文后,不需要给出任何确认,并且不保证数据不丢失,不保证是否顺序到达,也即UDP的传输服务不可靠。TCP提供可靠的传输服务,在传递数据之前通过三次握手建立连接,而且在传递数据时,有确认、窗口、重传、拥塞控制机制。通过TCP传输的数据无差错、不丢失、不重复并且按序到达。
- 是否有状态:UDP是无状态的服务,也即不管发出去之后的事。TCP传输是有状态的,会记录自己发送消息的状态,比如是否发送、是否被接受等等。
- 传输效率:由于TCP在传输时多了连接、确认、重传等机制,所以TCP的传输效率要比UDP低很多。
- 传输形式:UDP是面向报文的,TCP是面向字节流的。
- 首部开销:TCP首部开销(20-60字节)比UDP首部开销(8字节)要大。
- 是否提供广播或多播服务:TCP只支持点对点通信,UDP支持一对一、一对多、多对一、多对多。
TCP | UDP | |
---|---|---|
是否面向连接 | 是 | 否 |
是否可靠 | 是 | 否 |
是否有状态 | 是 | 否 |
传输效率 | 较慢 | 较快 |
传输形式 | 字节流 | 数据报文段 |
首部开销 | 20 ~ 60字节 | 8字节 |
是否提供广播或多播服务 | 否 | 是 |
4.2 什么时候选择TCP,什么时候选择UDP?
- UDP一般用于即时通信,比如:语音、视频、直播等,这些场景对于传输数据的准确性要求不是特别高。
- TCP用于对传输准确性要求特别高的场景,比如文件传输、收发邮件、远程登录等。
4.3 HTTP是基于TCP还是UDP?
需要分版本讨论,在HTTP1.0、1.1、2.0中,是基于TCP协议的,而3.0中HTTP基于UDP的QUIC协议。
通过这个变化解决了2.0中的队头阻塞问题,同时还避免了TCP三次握手的延迟,允许在第一次连接时就发送数据。
4.4 使用TCP和UDP的协议分别有哪些?
4.4.1 使用TCP的协议
- HTTP:超文本传输协议(HTTP,HyperText Transfer Protocol)是一种用于传输超文本和多媒体内容的协议,主要是为 Web 浏览器与 Web 服务器之间的通信而设计的。当我们使用浏览器浏览网页的时候,我们网页就是通过 HTTP 请求进行加载的。
- HTTPS:更安全的超文本传输协议(HTTPS,Hypertext Transfer Protocol Secure),身披 SSL 外衣的 HTTP 协议。
- FTP:文件传输协议 FTP(File Transfer Protocol)是一种用于在计算机之间传输文件的协议,可以屏蔽操作系统和文件存储方式。
- SMTP:简单邮件传输协议(SMTP,Simple Mail Transfer Protocol)的缩写,是一种用于发送电子邮件的协议。
- POP3/IMAP:两者都是负责邮件接收的协议。IMAP 协议是比 POP3 更新的协议,它在功能和性能上都更加强大。IMAP 支持邮件搜索、标记、分类、归档等高级功能,而且可以在多个设备之间同步邮件状态。几乎所有现代电子邮件客户端和服务器都支持 IMAP。
- SSH:SSH( Secure Shell)是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议。
4.4.2 使用UDP的协议
- DHCP:动态主机配置协议,动态配置 IP 地址
- DNS:域名系统(DNS,Domain Name System)将人类可读的域名 (例如,www.baidu.com) 转换为机器可读的 IP 地址 (例如,220.181.38.148)。 我们可以将其理解为专为互联网设计的电话薄。
4.5 TCP三次握手和四次挥手
4.5.1 说一说什么是三次握手?
建立一个TCP连接需要三次握手,缺一不可。

- 一次握手:客户端发送带有SYN(SEQ=x)标志的数据包到服务器,然后客户端进入SYN_SENT状态,等待服务器的确认。
- 二次握手:服务器发送带有SYN+ACK(SEQ=y,ACK=x+1)标志的数据包给客户端,然后服务器进入SYN_RECV状态。
- 三次握手:客户端发送带有ACK(ACK=y+1)标志的数据包给服务器,然后客户端和服务器都进入ESTABLISHED状态,完成三次握手。
当完成三次握手之后,客户端和服务器之间就可以传输数据了。
4.5.2 为什么要进行三次握手?(为什么不是两次或四次握手?)
因为TCP采用的是全双工通信,进行三次握手的目的是建立可靠的通信信道,最主要的目的就是客户端和服务器双方确认自己与对方的发送和接收功能是正常的。
- 第一次握手作用就是服务器确认:对方发送正常,自己接收正常。
- 第二次握手作用就是客户端确认:自己发送、接收正常,对方发送、接收正常;服务器确认:对方发送正常、自己接受正常。
- 第三次握手作用就是客户端确认:自己发送、接收正常,对方发送、接收正常;服务器确认:自己发送、接收正常,对方发送、接收正常。
三次握手就能刚好确认双方收发功能正常,缺一不可。
- 三次握手才可以阻止重复历史连接的初始化,防止旧的重复连接初始化造成混乱。
- 三次握手才可以同步双方的初始序列号。
- 三次握手才可以避免资源浪费。
4.5.3 第二次握手传回了ACK,为什么还要传回SYN?
服务器传回给客户端ACK是为了告诉客户端:“我收到的信息确实是你发的信息”,这表明客户端到服务器之间的通信是正常的,而传回SYN是为了建立并确认从服务器到客户端的通信正常。
4.5.4 说一说什么是四次挥手?
断开TCP连接需要四次挥手,缺一不可。

- 第一次挥手:客户端发送一个FIN(SEQ=x)标志的数据包给服务器,用来关闭客户端到服务器的数据传输。然后,客户端进入FIN-WAIT-1状态。
- 第二次挥手:服务器收到这个FIN(SEQ=x)标志的数据包,它发送一个ACK(SEQ=x+1)标志的数据包给客户端。然后此时服务器进入CLOSED-WAIT状态,客户端收到数据包后进入FIN-WAIT-2状态。
- 第三次挥手:服务器关闭与客户端之间的连接,并发送一个FIN(SEQ=y)标志的数据包给客户端,请求关闭连接,然后服务器进入LAST-ACK状态。
- 第四次挥手:客户端收到FIN数据包后,发送ACK(SEQ=y+1)标志的数据包给服务器,并且进入TIME_WAIT状态,服务器在收到ACK(SEQ=y+1)标志的数据包后进入CLOSE状态。此时客户端等待2MSL后依然没有收到回复,就证明服务器已经正常关闭,随后客户端也就可以正常关闭了,也变成CLOSE状态。
只要四次挥手没有结束,客户端和服务器之间就可以继续传输数据。
4.5.5 为什么要四次挥手?
TCP 是全双工通信,可以双向传输数据。任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后就完全关闭了 TCP 连接。
比如,A和B打电话,即将结束时:
- 第一次挥手:A说:我没什么要说的了。
- 第二次挥手:B说:我知道了,但是B可能还有要说的话,A不能因为自己没什么要说的了就中断对话。
- 第三次挥手:B巴拉巴拉说了一通,B终于说:我说完了。
- 第四次挥手:A说:我知道了,这样双方都没什么说的了,对话才算结束。
4.5.6 为什么不把服务器发送的ACK和FIN合并,变成三次挥手?
因为服务器在收到客户端发送的断开连接请求时,可能还有一些数据没有发送完,所以这时候先发送ACK,表示收到了你要断开连接的请求。等我这些数据发完,再发送FIN,表示我数据发完了,可以断开连接了。
4.5.7 如果第二次挥手时,服务器的ACK没有送到客户端会发生什么?
客户端没有收到ACK确认,会重新发送FIN请求,继续第一次挥手的操作。
4.5.8 为什么第四次挥手客户端需要等待 2*MSL(报文段最长寿命)时间后才进入 CLOSED 状态?
第四次挥手时,客户端发送给服务器的 ACK 有可能丢失,如果服务端因为某些原因而没有收到 ACK 的话,服务端就会重发 FIN,如果客户端在 2*MSL 的时间内收到了 FIN,就会重新发送 ACK 并再次等待 2MSL,所以一来一回需要等待 2 倍的时间。 2MSL时长 这其实是相当于至少允许报文丢失一次。防止服务器没有收到 ACK 而不断重发 FIN。
4.6 TCP传输可靠性保障?
4.6.1 TCP如何保证传输的可靠性?
- 基于数据块传输:应用数据被分割成TCP认为最适合发送的数据块,再传输给网络层,数据块被称为报文段或段。
- 对失序数据包重新排序以及去重:TCP为了保证不发生丢包,就给每个包一个序列号,有了序列号就能将接收到的数据根据序列号排序,并且去掉重复序列号的数据就可以实现数据包去重。
- 校验和:TCP将保持它首部和数据的校验和。这是一个端到端的校验和,目的是检测数据在传输过程中的任何变化。如果收到段的校验和有差错,TCP将丢弃这个报文段和不确认收到此报文段。
- 超时重传:当发送方发送数据之后,它启动一个定时器,等待目的端确认收到这个报文段。接收端实体对已成功收到的包发回一个相应的确认信息(ACK)。如果发送端实体在合理的往返时延(RTT)内未收到确认消息,那么对应的数据包就被假设为已丢失并进行重传。
- 流量控制:TCP 连接的每一方都有固定大小的缓冲空间,TCP 的接收端只允许发送端发送接收端缓冲区能接纳的数据。当接收方来不及处理发送方的数据,能提示发送方降低发送的速率,防止包丢失。TCP 使用的流量控制协议是可变大小的滑动窗口协议(TCP 利用滑动窗口实现流量控制)。
- 拥塞控制:当网络拥塞时,减少数据的发送。
4.6.2 TCP如何实现流量控制?
TCP利用滑动窗口实现流量控制。其目的是为了控制发送方发送数据的速率,保证接收方来得及接收。接收方发送的确认报文中,窗口字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。将窗口字段设置为0时,发送方不能发送数据。
4.6.3 为什么要进行流量控制?
双方在通信时,发送方的速率和接收方的速率不一定是相等的,如果发送方的发送速率太快,会导致接收方处理不过来。如果接收方处理不过来的话,就只能把数据存在接收缓冲区里。如果缓冲区满了,发送方还在发送数据的话,接收方只能把收到的数据包丢掉,浪费网络资源。所以要控制发送方的发送速率,让两者处于一种动态平衡。
注意:发送方不等于客户端,接收端也不等于服务器。
因为TCP是全双工通信,双方都可以进行双向通信。
4.6.4 发送窗口和接收窗口
1.TCP发送窗口可以划分为四个部分
- 发送已确认;
- 发送未确认;
- 未发可发送;
- 不可发送;

发送窗口大小 = 发送未确认 + 未发可发送
。
2.TCP接收窗口可以划分为三个部分
- 已收已确认;
- 等待接收;
- 不能接收;

接收窗口的大小 = 等待接收
可以根据接收端处理数据的速度动态调整的。
接收窗口的大小约等于发送窗口的大小,
4.6.5 TCP如何实现拥塞控制?
拥塞控制就是为了防止过多的数据注入到网络中,这样就可以使网络中的路由器或链路不致过载。拥塞控制所要做的都有一个前提,就是网络能够承受现有的网络负荷。拥塞控制是一个全局性的过程,涉及到所有的主机,所有的路由器,以及与降低网络传输性能有关的所有因素。相反,流量控制往往是点对点通信量的控制,是个端到端的问题。流量控制所要做到的就是抑制发送端发送数据的速率,以便使接收端来得及接收。

为了进行拥塞控制,TCP 发送方要维持一个 拥塞窗口(cwnd) 的状态变量。拥塞控制窗口的大小取决于网络的拥塞程度,并且动态变化。发送方让自己的发送窗口取为拥塞窗口和接收方的接受窗口中较小的一个。
TCP 的拥塞控制采用了四种算法,即 慢开始 、 拥塞避免 、快重传 和 快恢复。在网络层也可以使路由器采用适当的分组丢弃策略(如主动队列管理 AQM),以减少网络拥塞的发生。
慢开始: 慢开始算法的思路是当主机开始发送数据时,如果立即把大量数据字节注入到网络,那么可能会引起网络阻塞,因为现在还不知道网络的符合情况。经验表明,较好的方法是先探测一下,即由小到大逐渐增大发送窗口,也就是由小到大逐渐增大拥塞窗口数值。cwnd 初始值为 1,每经过一个传播轮次,cwnd 加倍。
拥塞避免: 拥塞避免算法的思路是让拥塞窗口 cwnd 缓慢增大,即每经过一个往返时间 RTT 就把发送方的 cwnd 加 1。
快重传与快恢复: 在 TCP/IP 中,快速重传和恢复(fast retransmit and recovery,FRR)是一种拥塞控制算法,它能快速恢复丢失的数据包。没有 FRR,如果数据包丢失了,TCP 将会使用定时器来要求传输暂停。在暂停的这段时间内,没有新的或复制的数据包被发送。有了 FRR,如果接收机接收到一个不按顺序的数据段,它会立即给发送机发送一个重复确认。如果发送机接收到三个重复确认,它会假定确认件指出的数据段丢失了,并立即重传这些丢失的数据段。有了 FRR,就不会因为重传时要求的暂停被耽误。 当有单独的数据包丢失时,快速重传和恢复(FRR)能最有效地工作。当有多个数据信息包在某一段很短的时间内丢失时,它则不能很有效地工作。
4.6.6 什么是ARQ协议?
自动重传请求ARQ是OSI模型中数据链路层和传输层的错误纠正协议之一。通过确认和超时这两个机制,在不可靠服务的基础上实现可靠的信息传输。
如果发送方在发送后一段时间内没有收到确认信息,也即ACK,通常会重新发送,直到收到确认或者重试超过一定次数。
ARQ协议包括停止等待ARQ协议和连续ARQ协议。
- 停止等待ARQ协议:为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认(回复 ACK)。如果过了一段时间(超时时间后),还是没有收到 ACK 确认,说明没有发送成功,需要重新发送,直到收到确认后再发下一个分组;在停止等待协议中,若接收方收到重复分组,就丢弃该分组,但同时还要发送确认。
- 连续 ARQ 协议:可提高信道利用率。发送方维持一个发送窗口,凡位于发送窗口内的分组可以连续发送出去,而不需要等待对方确认。接收方一般采用累计确认,对按序到达的最后一个分组发送确认,表明到这个分组为止的所有分组都已经正确收到了。
4.7 什么是SYN攻击?
大量的握手请求涌向 TCP 服务端,而它们只发出 SYN 报文而不以 ACK响应结束握手,服务端就要为这每一个请求都维持约一分多钟的连接去等待 ACK, 从而额外消耗很多服务器的网络连接资源,导致服务端较长时间内丧失服务功能。
其中最经典的就是 DoS(Denial of Service 拒绝服务)攻击。
SYN 攻击方式最直接的表现就会把 TCP 半连接队列打满,这样当 TCP 半连接队列满了,后续再在收到 SYN 报文就会丢弃,导致客户端无法和服务端建立连接。
4.7.1 如何避免SYN攻击?
- 调大网络接口队列长度,提高网络接口吞吐能力和抗压能力;
- 增大TCP半连接队列;
- 开启SYN Cookie技术;
- 减少SYN+ACK重传次数;
4.8 拔掉网线后,原本的TCP连接还存在吗?
客户端拔掉网线后,并不会直接影响 TCP 连接状态。所以,拔掉网线后,TCP 连接是否还会存在,关键要看拔掉网线之后,有没有进行数据传输。
有数据传输的情况:
- 在客户端拔掉网线后,如果服务端发送了数据报文,那么在服务端重传次数没有达到最大值之前,客户端就插回了网线,那么双方原本的 TCP 连接还是能正常存在,就好像什么事情都没有发生。
- 在客户端拔掉网线后,如果服务端发送了数据报文,在客户端插回网线之前,服务端重传次数达到了最大值时,服务端就会断开 TCP 连接。等到客户端插回网线后,向服务端发送了数据,因为服务端已经断开了与客户端相同四元组的 TCP 连接,所以就会回 RST 报文,客户端收到后就会断开 TCP 连接。至此, 双方的 TCP 连接都断开了。
没有数据传输的情况:
- 如果双方都没有开启 TCP keepalive 机制,那么在客户端拔掉网线后,如果客户端一直不插回网线,那么客户端和服务端的 TCP 连接状态将会一直保持存在。
- 如果双方都开启了 TCP keepalive 机制,那么在客户端拔掉网线后,如果客户端一直不插回网线,TCP keepalive 机制会探测到对方的 TCP 连接没有存活,于是就会断开 TCP 连接。而如果在 TCP 探测期间,客户端插回了网线,那么双方原本的 TCP 连接还是能正常存在。
4.9 什么是粘包和拆包?发生的原因是什么?
一个完整的业务可能会被TCP拆分成多个包进行发送,也有可能把多个小的数据包封装成一个大的数据包发送,这个就是TCP的拆包和粘包问题。
4.9.1 拆包
- 要发送的数据大于TCP发送方缓冲区剩余空间大小,将会发生拆包;
- 待发送数据大于最大报文长度,TCP在传输前将进行拆包;
4.9.2 粘包
- 要发送的数据小于TCP发送缓冲区的大小,TCP将多次写入缓冲区的数据一次发送出去,将会发生粘包;
- 接收数据端的应用层没有及时读取接收缓冲区中的数据,会导致数据包堆积,也会发生粘包;
4.9.3 解决方案
- 固定消息的长度。 发送端将每个数据包封装为固定长度(不够的可以通过补0填充),这样接收端每次从缓冲区中读取固定长度的数据,这就自然而然的把每个数据包拆分开来;
- 设置消息边界:比如在数据包末尾增加特殊字符或特殊标记进行分割;
- 将消息分为消息头和消息体:消息头中包含表示消息总长度的字段,消息体是要读取的内容;
- 使用其它复杂的协议。
4.9.4 UDP会不会粘包?
不会,因为UDP不像TCP是面向字节流的,而是面向消息的协议,每一个UDP段都是一条消息,应用程序必须以消息为单位提取数据,不能一次提取任意字节的数据。所谓粘包问题主要还是因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的。
UDP是无连接的,面向消息的,提供高效率服务。不会使用块的合并优化算法,由于UDP支持的是一对多的模式,所以接收端采用了链式结构来记录每一个到达的UDP包,在每个UDP包中就有了消息头(消息来源地址,端口等信息),这样,对于接收端来说,就容易进行区分处理了。 即面向消息的通信是有消息保护边界的。
4.9.5 UDP什么情况下会丢包呢?
- 接收端处理时间过长导致丢包:调用recv方法接收端收到数据后,处理数据花了一些时间,处理完后再次调用recv方法,在这二次调用间隔里,发过来的包可能丢失。对于这种情况可以修改接收端,将包接收后存入一个缓冲区,然后迅速返回继续recv。
- 发送的包巨大丢包:虽然send方法会帮你做大包切割成小包发送的事情,但包太大也不行。例如超过50K的一个udp包,不切割直接通过send方法发送也会导致这个包丢失。这种情况需要切割成小包再逐个send。
- 发送的包较大,超过接受者缓存导致丢包:几个大的udp包可能会超过接收者的缓冲,导致丢包。这种情况可以设置socket接收缓冲。
- 发送的包频率太快:也有可能导致丢包。可以在发送频率过快的时候还是考虑sleep一下。
五、IP
5.1 IP协议的作用是什么?
IP(Internet Protocol,网际协议) 是 TCP/IP 协议中最重要的协议之一,属于网络层的协议,主要作用是定义数据包的格式、对数据包进行路由和寻址,以便它们可以跨网络传播并到达正确的目的地。
目前 IP 协议主要分为两种,一种是过去的 IPv4,另一种是较新的 IPv6,目前这两种协议都在使用。
5.2 什么是IP地址?IP寻址如何工作?
每个连入互联网的设备或域(如计算机、服务器、路由器等)都被分配一个 IP 地址(Internet Protocol address),作为唯一标识符。每个 IP 地址都是一个字符序列,如 192.168.1.1(IPv4)、2001:0db8:85a3:0000:0000:8a2e:0370:7334(IPv6)。
当网络设备发送 IP 数据包时,数据包中包含了 源 IP 地址 和 目的 IP 地址 。
源 IP 地址用于标识数据包的发送方设备或域,而目的 IP 地址则用于标识数据包的接收方设备或域。这类似于一封邮件中同时包含了目的地地址和回邮地址。
网络设备根据目的 IP 地址来判断数据包的目的地,并将数据包转发到正确的目的地网络或子网络,从而实现了设备间的通信。
这种基于 IP 地址的寻址方式是互联网通信的基础,它允许数据包在不同的网络之间传递,从而实现了全球范围内的网络互联互通。IP 地址的唯一性和全局性保证了网络中的每个设备都可以通过其独特的 IP 地址进行标识和寻址。

5.3 什么是IP地址过滤?
简单来说就是限制或阻止特定IP地址或IP地址范围的访问。比如,有个图片服务突然被某一IP地址攻击,那我们就可以禁止这个IP地址访问图片服务。
IP地址过滤是一种简单的网络安全措施,实际应用中一般还会结合其他的网络安全措施,比如认证、授权、加密等等。
5.4 IPv4和IPv6有什么区别?
IPv4(Internet Protocol version 4) 是目前广泛使用的 IP 地址版本,其格式是四组由点分隔的数字,例如:123.89.46.72。IPv4 使用 32 位地址作为其 Internet 地址,这意味着共有约 42 亿( 2^32)个可用 IP 地址。
为了解决 IP 地址耗尽的问题,最根本的办法是采用具有更大地址空间的新版本 IP 协议 - IPv6(Internet Protocol version 6)。IPv6 地址使用更复杂的格式,该格式使用由单或双冒号分隔的一组数字和字母,例如:2001:0db8:85a3:0000:0000:8a2e:0370:7334 。可以使用 128 位互联网地址,这意味着越有 2^128(3 开头的 39 位数字,恐怖如斯) 个可用 IP 地址。
除了更大的地址空间之外,IPv6 的优势还包括:
- 无状态地址自动配置(Stateless Address Autoconfiguration,简称 SLAAC) :主机可以直接通过根据接口标识和网络前缀生成全局唯一的 IPv6 地址,而无需依赖 DHCP(Dynamic Host Configuration Protocol)服务器,简化了网络配置和管理。
- NAT(Network Address Translation,网络地址转换) 成为可选项 :IPv6 地址资源充足,可以给全球每个设备一个独立的地址。
- 对标头结构进行了改进 :IPv6 标头结构相较于 IPv4 更加简化和高效,减少了处理开销,提高了网络性能。
- 可选的扩展头 :允许在 IPv6 标头中添加不同的扩展头(Extension Headers),用于实现不同类型的功能和选项。
- ICMPv6(Internet Control Message Protocol for IPv6) :IPv6 中的 ICMPv6 相较于 IPv4 中的 ICMP 有了一些改进,如邻居发现、路径 MTU 发现等功能的改进,从而提升了网络的可靠性和性能。
5.5 NAT的作用是什么?
网络地址转换主要用于不同网络之间转换IP地址。它允许将私有IP地址(局域网中使用的IP地址)映射为公有IP地址(互联网中使用的IP地址)或者反向映射,从而实现局域网内多个设备通过单一公有IP地址访问互联网。
NAT 不光可以缓解 IPv4 地址资源短缺的问题,还可以隐藏内部网络的实际拓扑结构,使得外部网络无法直接访问内部网络中的设备,从而提高了内部网络的安全性。

六、ARP
6.1 什么是MAC地址?
MAC 地址的全称是 媒体访问控制地址(Media Access Control Address)。如果说,互联网中每一个资源都由 IP 地址唯一标识(IP 协议内容),那么一切网络设备都由 MAC 地址唯一标识。
可以理解为,MAC 地址是一个网络设备真正的身份证号,IP 地址只是一种不重复的定位方式(比如说住在某省某市某街道的张三,这种逻辑定位是 IP 地址,他的身份证号才是他的 MAC 地址),也可以理解为 MAC 地址是身份证号,IP 地址是邮政地址。MAC 地址也有一些别称,如 LAN 地址、物理地址、以太网地址等。
MAC 地址的长度为 6 字节(48 比特),地址空间大小有 280 万亿之多。
前 24 比特由 IEEE 统一管理,保证不会重复。而后 24 比特,由各家生产商自己管理,同样保证生产的两块网卡的 MAC 地址不会重复。
MAC 地址具有可携带性、永久性,身份证号永久地标识一个人的身份,不论他到哪里都不会改变。而 IP 地址不具有这些性质,当一台设备更换了网络,它的 IP 地址也就可能发生改变,也就是它在互联网中的定位发生了变化。
MAC 地址有一个特殊地址:FF-FF-FF-FF-FF-FF(全 1 地址),该地址表示广播地址。
6.2 ARP协议解决了什么问题?
ARP协议全称地址解析协议,它解决的是网络层地址与链路层地址间的转换问题。因为一个IP数据报在物理上传输的过程中,总是需要知道下一跳的目的地,但是IP地址属于逻辑地址,而MAC地址才是物理地址,而ARP协议解决了IP地址转MAC地址的一些问题。
6.3 ARP协议工作原理?
ARP 协议工作时有一个大前提,那就是 ARP 表。
在一个局域网内,每个网络设备都自己维护了一个 ARP 表,ARP 表记录了某些其他网络设备的 IP 地址-MAC 地址映射关系,该映射关系以 <IP, MAC, TTL>
三元组的形式存储。其中,TTL 为该映射关系的生存周期,典型值为 20 分钟,超过该时间,该条目将被丢弃。
ARP 的工作原理将分两种场景讨论:
- 同一局域网内的 MAC 寻址;
- 从一个局域网到另一个局域网中的网络设备的寻址。
6.3.1 同一局域网内的MAC寻址
假设当前有如下场景:IP 地址为137.196.7.23
的主机 A,想要给同一局域网内的 IP 地址为137.196.7.14
主机 B,发送 IP 数据报文。
再次强调,当主机发送 IP 数据报文时(网络层),仅知道目的地的 IP 地址,并不清楚目的地的 MAC 地址,而 ARP 协议就是解决这一问题的。
为了达到这一目标,主机A只能通过ARP协议来获取主机B的MAC地址,并将IP报文封装成链路层帧,发送到下一跳。在该局域网内,将发生以下事情:
主机A检索自己的ARP表,发现ARP表中并无主机B的IP地址对应的映射条目,也就无从知道主机B的MAC地址。
主机A构建一个ARP查询分组,并将其广播到所在的局域网中。
ARP分组是一种特殊报文,主要有两类,一类是查询分组、一类是响应分组,具有相同的格式,均包含了发送和接收的IP地址、发送和接收的MAC地址。在查询分组中,发送的IP地址,也就是主机A的IP地址,接收的IP地址就是主机B的IP地址,发送的MAC地址就是主机A的MAC地址,但是接收的MAC地址并不是主机B的MAC地址(因为这就是需要查询的),而是一个特殊值
FF-FF-FF-FF-FF-FF
,也就是前面说的特殊地址,广播地址,也即查询分组将广播给该局域网内的所有设备。主机A构造的查询分组将在该局域网内进行广播,理论上每个设备都会收到该分组,并检查查询分组的接收IP地址是否为自己的IP地址,如果是,那么说明查询分组已经找到了主机B,否则,这个查询分组对于当前设备无效,当前设备会将这个查询分组丢弃。
主机B收到了查询分组后,验证是对自己的问询,然后构造一个ARP响应分组,该分组的目的地只有一个——主机A,发送给主机A。同时主机B提取查询分组中主机A的IP地址和MAC地址信息,在自己的ARP表中构造一条主机A的IP-MAC映射记录。
ARP响应分组和ARP查询分组有相同的构造,不同的是,发送和接收的IP地址相反,发送的MAC地址为发送者本身,也即主机B的MAC地址,目标MAC地址为查询分组的发送者,也即主机A的MAC地址,也就是说ARP响应分组只有一个目的地,而不是查询分组那样是一个广播。
主机A收到了主机B的响应分组,提取出该分组中主机B的IP地址和MAC地址后,构造映射信息,加入到自己的ARP表中。

再整个过程中,需要补充几点:
- 主机A想给主机B发送IP数据报,如果主机B的IP-MAC映射信息已经存在于主机A的ARP表中,那么就不需要广播,直接提取MAC地址并构造链路层帧发送就行。
- ARP表中的映射信息是有生存周期的,一般为20分钟。
- 目标主机接受到了问询主机构造的问询报文后,将先把问询主机的IP-MAC映射存进自己ARP表中,这样才能获取到响应目标MAC地址,以便顺利发送响应分组。
总的来说ARP协议是一个广播问询,单播响应协议。
6.3.2 不同局域网内的MAC寻址
更复杂的情况是,发送主机 A 和接收主机 B 不在同一个子网中,假设一个一般场景,两台主机所在的子网由一台路由器联通。这里需要注意的是,一般情况下,我们说网络设备都有一个 IP 地址和一个 MAC 地址,这里说的网络设备,更严谨的说法应该是一个接口。路由器作为互联设备,具有多个接口,每个接口同样也应该具备不重复的 IP 地址和 MAC 地址。因此,在讨论 ARP 表时,路由器的多个接口都各自维护一个 ARP 表,而非一个路由器只维护一个 ARP 表。
主机A查询ARP表,希望找到目标路由器的本子网接口的MAC地址。
目标路由器是指,根据目的主机B的IP地址,分析出B所在的子网,能够把报文转发到B所在子网的那个路由器。
主机A没找到,采用ARP协议,问询到该MAC地址,由于目标接口与主机A在同一个子网中,该过程与同一局域网内的MAC寻址相同。
主机A获取到目标接口的MAC地址,先构造IP数据报,其中源IP是A的IP地址,目的IP地址是B的IP地址,再构造链路层帧,其中源MAC地址是A的MAC地址,目的MAC地址是本子网内与路由器连接的接口的MAC地址。主机A将把这个链路层帧,以单播的方式,发送给目标接口。
目标接口接收到了主机A发来的链路层帧,解析,根据目的IP地址,查询转发表,将该IP数据报转发到与主机B所在子网相连的接口上。
到此,该帧已经从主机A所在的子网,转移到主机B所在的子网中了。
路由器接口查询ARP表,希望找到主机B的MAC地址。
路由器接口如果没找到,将采用ARP协议,广播问询,单播响应,获取到主机B的MAC地址。
路由器接口将对IP数据报重新封装成链路层帧,目标MAC地址为主机B的MAC地址,单播发送,直到到达目的地。
