背景
在说 TCP、UDP 之前,咱们先了解一下计算机网络吧,毕竟这两个协议的霸霸是传输层,而传输层又是计算机网络的七层协议之一。那么为什么我们要学习计算机网络呢?因为大厂面试必问,甚至一些创业公司有做开发的,那么你去面试的时候大概率也会被问到,然而现实是,咱们很多人回答的确实是不怎么好,也包括我自己,在开始的时候。我说一下我自己的面试历程吧。早在 2015 年刚毕业的时候,我去了广州某游戏公司面试,问了一个 socket,当时我的心里是
东拉西扯聊了半个小时,估计面试官的心里是这么想的
当时刚毕业,所以很多东西还是有印象的,但是始终回答的不够到位,逻辑不够清晰,或者不够深入,那个时候自己心里还是mmp 的,于是下定决心整理,后来妈妈再也不用担心我面试的时候碰到网络相关的问题了。
所以在这里,我总结了一些问题,这些问题在各大网站都能找到答案,但是还是希望你耐心看完下面的内容,当你看完以后,你一定会有所收获的!!!
计算机网络的七层是什么?
计算机网络七层就是 媒介层和主机层。
其中媒介层包括物理层、数据链路层和网络层;主机层包括传输层、会话层、表示层、应用层。
- 第七层:应用层
定义了用于在网络中进行通信和数据传输的接口 - 用户程式;提供标准服务,比如虚拟终端、文件以及任务的传输和处理;
- 第六层:表示层
掩盖不同系统间的数据格式的不同性; 指定独立结构的数据传输格式; 数据的编码和解码;加密和解密;压缩和解压缩
- 第五层:会话层
管理用户会话和对话; 控制用户间逻辑连接的建立和挂断;报告上一层发生的错误
- 第四层:传输层
管理网络中端到端的信息传送; 通过错误纠正和流控制机制提供可靠且有序的数据包传送;提供面向无连接的数据包的传送;
- 第三层:网络层
定义网络设备间如何传输数据;根据唯一的网络设备地址路由数据包;提供流和拥塞控制以防止网络资源的损耗
- 第二层:数据链路层
定义操作通信连接的程序;封装数据包为数据帧;监测和纠正数据包传输错误
- 第一层:物理层
定义通过网络设备发送数据的物理方式;作为网络媒介和设备间的接口;定义光学、电气以及机械特性。
五层结构(我们在面试中也经常听到说,谈下你对五层网络协议体系结构的理解?)
五层结构其实是把七层结构的应用层、表示层、会话层合在一起,统一叫做应用层。
为什么要分层?
1)各层之间相互独立:高层是不需要知道底层的功能是采取硬件技术来实现的,它只需要知道通过与底层的接口就可以获得所需要的服务;
2)灵活性好:各层都可以采用最适当的技术来实现,例如某一层的实现技术发生了变化,用硬件代替了软件,只要这一层的功能与接口保持不变,实现技术的变化都并不会对其他各层以及整个系统的工作产生影响;
3)易于实现和标准化:由于采取了规范的层次结构去组织网络功能与协议,因此可以将计算机网络复杂的通信过程,划分为有序的连续动作与有序的交互过程,有利于将网络复杂的通信工作过程化解为一系列可以控制和实现的功能模块,使得复杂的计算机网络系统变得易于设计,实现和标准化
https://blog.csdn.net/kerin_lu/java/article/details/11808481
什么HTPP 协议?
HTTP(Hypertext Transfer Protocol) 超文本传输协议,他有请求报文和响应报文,HTTP请求前要先建立连接,所以它是无连接和无状态。
请求报文格式
HTTP 请求报文主要由四部分组成,请求行、请求头、空行、请求体
- HTTP的请求报文第一行叫做请求行,其后继的为首部行。
请求行有三个字段:方法字段(GET、POST、HEAD、PUT、DELETE、OPTIONS),URL字段,HTTP(协议版本) 版本字段 - 请求头部字段,通过键值的形式进行添加
- 最后一行就是我们常说的请求主体(Body)
响应报文
HTTP响应也由四个部分组成,分别是:响应行、响应头、空行、响应体。
- 响应行:包括协议版本、状态码、状态短语
其中状态码,状态码 :状态码负责表示客户端请求的返回结果、标记服务器端是否正常、通知出现的错误。状态代码由三位数字组成,第一个数字定义了响应的类别,且有五种可能取值
- 响应头:响应头部字段
- 响应体:data 里面的数据
HTTP 常见状态码:
HTTP 是如何建立连接的?
三次握手,怎么理解呢?猎头找人为例子吧
猎头:喂,是某某某么?
你:是,我是某某某
猎头:好的
此时猎头和你已经建立联系了,开始推销职位。Balabala
想要了解更多,继续往下看,在 TCP 的部分会着重介绍三次握手和四次挥手
HTTP 如何保持持久链接?
HTTP1.0 默认是不开启长链接,在请求头里面设置Connection:Keep-Alive, HTTP1.1以后是默认开启的。
HTTP 长连接不可能一直保持,例如 Keep-Alive: timeout=5, max=100,表示这个TCP通道可以保持5秒,max=100,表示这个长连接最多接收100次请求就断开。
怎么样去判断当前 HTTP请求结束?
使用长连接之后,客户端、服务端怎么知道本次传输结束呢?两部分:
- 判断传输数据是否达到了Content-Length 指示的大小;
- 动态生成的文件没有 Content-Length ,它是分块传输(chunked),这时候就要根据 chunked 编码来判断,chunked 编码的数据在最后有一个空 chunked 块,表明本次传输数据结束。
在浏览器中输入 URL 按下回车,它做了什么?
- DNS域名解析;
- 建立TCP连接;
- 发送HTTP请求;
- 服务器处理请求;
- 返回响应结果;
- 关闭TCP连接;
- 浏览器解析HTML;
- 浏览器布局渲染;
TCP 和 UDP 的区别?
- UDP 特点是无连接,面向报文,尽最大努力交付,差错检测、复用、分用
- TCP 面向连接,面向字节流,可靠传输的
UDP的报文结构
首先我们来看看 UDP 的报文结构是什么样的,如下图
应用层数据占用UDP报文段的数据字段。UDP首部只有4个字段,每个字段由2个字节组成,即UDP首部仅有8字节。
- 端口号:可以使目的主机将应用数据交给运行在目的端系统中端相应进程,执行分用功能。
- 长度:该字段指示了在UDP报文段中的字节数(首部+数据)
- 检验和:接收方使用检验和来检查在该报文段中是否出现了差错,即差错检测。
TCP 连接的三次握手和四次挥手
三次握手
从最开始双方都处于CLOSED状态。然后服务端开始监听某个端口,进入了LISTEN状态。
- 然后客户端主动发起连接,发送 SYN , 自己变成了SYN-SENT状态。
- 服务端接收到,返回SYN和ACK(对应客户端发来的SYN),自己变成了SYN-REVD。
- 之后客户端再发送ACK给服务端,自己变成了ESTABLISHED状态;服务端收到ACK之后,也变成了ESTABLISHED状态。
另外需要提醒你注意的是,从图中可以看出,SYN 是需要消耗一个序列号的,下次发送对应的 ACK 序列号要加1,为什么呢?只需要记住一个规则:
凡是需要对端确认的,一定消耗TCP报文的序列号。
SYN 需要对端的确认, 而 ACK 并不需要,因此 SYN 消耗一个序列号而 ACK 不需要。
为什么不是两次?
根本原因: 无法确认客户端的接收能力。
分析如下:
如果是两次,你现在发了 SYN 报文想握手,但是这个包滞留在了当前的网络中迟迟没有到达,TCP 以为这是丢了包,于是重传,两次握手建立好了连接。
看似没有问题,但是连接关闭后,如果这个滞留在网路中的包到达了服务端呢?这时候由于是两次握手,服务端只要接收到然后发送相应的数据包,就默认建立连接,但是现在客户端已经断开了。看到问题的吧,这就带来了连接资源的浪费。
https://juejin.im/post/5e527c58e51d4526c654bf41
四次挥手
- 客户主机发起连接释放的请求,设置FIN为1,当然,序号seq也会带上,这里假设为u;发送完毕后,客户端进入 FIN-WAIT-1 状态。
- 服务端接收到FIN 报文后,会返回一个ACK 报文回去,此时设置ACK为1,确认号为u + 1;表明自己接受到了客户端关闭连接的请求,但还没有准备好关闭连接。发送完毕后,服务器端进入 CLOSE-WAIT 状态,客户端接收到这个确认包之后,进入 FIN-WAIT-2 状态,等待服务器端关闭连接。
- 服务器端准备好关闭连接时,向客户端发送结束连接请求,FIN 置为1;发送完毕后,服务器端进入 LAST-ACK 状态,等待来自客户端的最后一个ACK。
- 客户端接收到服务端传来的FIN 报文后,知道服务器已经准备好关闭了,发送一个确认包,并进入 TIME-WAIT状态,等待可能出现的要求重传的ACK 报文;
为什么要四次挥手呢?
简单的理解 Client 到 Server 是全双工的,所以断开也要两端断开。
更加专业的回答:
- 为了保证客户端发送的最后一个ACK 报文能够到达服务器。我们必须假设网络是不可靠的,ACK 报文可能丢失。如果服务端发出FIN 报文后没有收到ACK 报文,就会重发FIN 报文,此时处于TIME-WAIT状态的客户端就会重发ACK 报文。当然,客户端也不能无限久的等待这个可能存在的FIN 报文,因为如果服务端正常接收到了ACK 报文后是不会再发FIN 报文的。因此,客户端需要设置一个计时器,那么等待多久最合适呢?所谓的MSL(Maximum Segment Lifetime)指一个报文在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL时间后,客户端都没有再次收到FIN 报文,那么客户端推断ACK 报文已经被服务器成功接收,所以结束TCP 连接。
- 第二,防止已失效的连接请求报文段出现在新的连接中。客户端在发送完最后一个ACK 报文后,再经过时间2MSL,就可以使由于网络不通畅产生的滞留报文段失效。这样下一个新的连接中就不会出现旧的连接请求报文。
TCP 的可靠传输是如何保证的?
停止等待协议是为了实现可靠传输的,它的基本原理就是每发完一个分组就停止发送,等待对方确认。在收到确认后再发下一个分组;在停止等待协议中,若接收方收到重复分组,就丢弃该分组,但同时还要发送确认。主要包括以下几种情况:无差错情况、出现差错情况(超时重传)、确认丢失和确认迟到、确认丢失和确认迟到。
TCP 的滑动窗口是什么?
TCP 利用滑动窗口实现流量控制的机制。滑动窗口(Sliding window)是一种流量控制技术。早期的网络通信中,通信双方不会考虑网络的拥挤情况直接发送数据。由于大家不知道网络拥塞状况,同时发送数据,导致中间节点阻塞掉包,谁也发不了数据,所以就有了滑动窗口机制来解决此问题。
TCP 中采用滑动窗口来进行传输控制,滑动窗口的大小意味着接收方还有多大的缓冲区可以用于接收数据。发送方可以通过滑动窗口的大小来确定应该发送多少字节的数据。当滑动窗口为 0 时,发送方一般不能再发送数据报,但有两种情况除外,一种情况是可以发送紧急数据,例如,允许用户终止在远端机上的运行进程。另一种情况是发送方可以发送一个 1 字节的数据报来通知接收方重新声明它希望接收的下一字节及发送方的滑动窗口大小。
TCP 利用滑动窗口实现流量控制。流量控制是为了控制发送方发送速率,保证接收方来得及接收。接收方发送的确认报文中的窗口字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。将窗口字段设置为 0,则发送方不能发送数据。
TCP 的慢启动快重传?
这里我们就要看 TCP 的拥塞控制了,拥塞控制和流量控制不同,前者是一个全局性的过程,而后者指点对点通信量的控制。在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏。这种情况就叫拥塞。
拥塞控制就是为了防止过多的数据注入到网络中,这样就可以使网络中的路由器或链路不致于过载。拥塞控制所要做的都有一个前提,就是网络能够承受现有的网络负荷。拥塞控制是一个全局性的过程,涉及到所有的主机,所有的路由器,以及与降低网络传输性能有关的所有因素。相反,流量控制往往是点对点通信量的控制,是个端到端的问题。流量控制所要做到的就是抑制发送端发送数据的速率,以便使接收端来得及接收。
为了进行拥塞控制,TCP 发送方要维持一个拥塞窗口(cwnd) 的状态变量。拥塞控制窗口的大小取决于网络的拥塞程度,并且动态变化。发送方让自己的发送窗口取为拥塞窗口和接收方的接受窗口中较小的一个。
TCP 的拥塞控制采用了四种算法,即:慢开始、拥塞避免、快重传和快恢复。在网络层也可以使路由器采用适当的分组丢弃策略(如:主动队列管理 AQM),以减少网络拥塞的发生。
慢开始算法的思路是当主机开始发送数据时,如果立即把大量数据字节注入到网络,那么可能会引起网络阻塞,因为现在还不知道网络的符合情况。经验表明,较好的方法是先探测一下,即由小到大逐渐增大发送窗口,也就是由小到大逐渐增大拥塞窗口数值。cwnd 初始值为 1,每经过一个传播轮次,cwnd 加倍。
拥塞避免
拥塞避免算法的思路是让拥塞窗口 cwnd 缓慢增大,即每经过一个往返时间 RTT 就把发送方的 cwnd 加 1。
快启动快恢复
在 TCP/IP 中,快速重传和快恢复(fast retransmit and recovery,FRR)是一种拥塞控制算法,它能快速恢复丢失的数据包。
没有 FRR,如果数据包丢失了,TCP 将会使用定时器来要求传输暂停。在暂停的这段时间内,没有新的或复制的数据包被发送。有了 FRR,如果接收机接收到一个不按顺序的数据段,它会立即给发送机发送一个重复确认。如果发送机接收到三个重复确认,它会假定确认件指出的数据段丢失了,并立即重传这些丢失的数据段。
有了 FRR,就不会因为重传时要求的暂停被耽误。当有单独的数据包丢失时,快速重传和快恢复(FRR)能最有效地工作。当有多个数据信息包在某一段很短的时间内丢失时,它则不能很有效地工作。
https://juejin.im/post/5d896cccf265da03bd055c87juejin.im什么是 DNS 解析?
域名到IP 地址的映射,DNS 解析请求采用 UDP 明文数据报的形式传输。客户端向 DNS 服务器获取连接的 IP 地址,然后用得到的 IP 地址去和服务端建立连接,这个就是 DNS 解析
DNS 解析的方式有几种?
DNS 解析方法:递归查询、迭代查询
DNS 劫持是什么?怎么避免?
DNS 劫持流程
解决方案
HttpDNS:Dns 常规解析是使用 dns 协议向 dns 服务器的 53 端口发送请求,而使用 httpDns 则是使用 http 协议向 dns 服务器的 80 端口发送请求解析
长连接:客户端与长连 Server 连接,长连 Server 通过 Http向 APIServer 发送请求,获取到 IP 地址,通过内网返回长连 Server。如下图
整理了三天,翻看的博文都附上了链接!还是那句话,走过路过点个赞再走呗。