目录

计网 八股文

计算机网络架构层次

你知道OSI七层参考模型吗

一. 物理层

负责物理传输媒介的传输,例如电缆、光纤或⽆线信号。主要作⽤是传输⽐特流(就是由 1、0 转化为电流强弱来进⾏传输,到达⽬的地后再转化为 1、0,也就是我们常说的数模转换与模数转换)。这⼀层的数据叫做⽐特

二. 数据链路层

建⽴逻辑连接、进⾏硬件地址寻址、差错校验等功能。定义了如何让格式化数据以帧为单位进⾏传输,以及如何控制对物理介质的访问。将⽐特组合成字节进⽽组合成帧,⽤ MAC 地址访问介质,传输单位是桢。交换机工作在这一层

三. 网络层

负责数据的路由和转发,选择最佳路径将数据从源主机传输到⽬标主机。它使⽤IP地址来标识不同主机和⽹络,并进⾏逻辑地址寻址。传输单位是数据报。常⻅的协议有ICMP、ARP、IP。路由器工作在这一层

四. 传输层

提供端到端的数据传输服务。它使⽤TCP(传输控制协议)和UDP(⽤户数据报协议)来管理数据传输。

五. 会话层

建⽴、管理和终⽌应⽤程序之间的会话连接。它处理会话建⽴、维护和终⽌,以及处理会话过程中的异常情况

六. 表示层

负责数据的格式转换、加密和解密,确保数据在不同系统之间的正确解释和呈现,也就是把计算机能够识别的东⻄转换成⼈能够能识别的东⻄(如图⽚、声⾳等)

七. 应用层

⽹络服务与最终⽤户的⼀个接⼝。这⼀层为⽤户的应⽤程序(例如电⼦邮件、⽂件传输和终端仿真)提供⽹络服务。常⻅的协议有:FTP、SMTP、HTTP、DNS

TCP/IP四层网络模型?

TCP/IP模型是⼀种⽤于组织和描述计算机⽹络通信的标准模型,它是互联⽹最常⽤的协议栈。TCP/IP模型由两个主要协议组成:TCP(Transmission Control Protocol)和IP(Internet Protocol)

应用层

该层与OSI模型的应⽤层和表示层以及会话层类似,提供直接与⽤户应⽤程序交互的接⼝。它为⽹络上的各种应⽤程序提供服务,如电⼦邮件(SMTP)、⽹⻚浏览(HTTP)、⽂件传输(FTP)等

传输层

传输层(Transport Layer):该层对应OSI模型的传输层 。它负责端到端的数据传输,提供可靠的、⽆连接的数据传输服务。主要的传输层协议有TCP(Transmission Control Protocol)和UDP(User Datagram Protocol)。TCP提供可靠的数据传输,确保数据的正确性和完整性;⽽UDP则是⽆连接的,适⽤于不要求可靠性的传输,如实时⾳频和视频流

网际层

该层对应OSI模型的 ⽹络层。主要协议是IP(Internet Protocol),它负责数据包的路由和转发,选择最佳路径将数据从源主机传输到⽬标主机。IP协议使⽤IP地址来标识主机和⽹络,并进⾏逻辑地址寻址

网络接口层

⽹络接⼝层(Link Layer):该层对应OSI模型的数据链路层和物理层。它负责物理传输媒介的传输,例如以太⽹、Wi-Fi等,并提供错误检测和纠正的功能。此外,⽹络接⼝层还包含硬件地址(MAC地址)的管理


HTTP

HTTPS和HTTP的区别?

  • HTTP:明⽂的⽅式在⽹络中传输数据,HTTPS 解决了HTTP 不安全的缺陷,在 TCP 和 HTTP ⽹络层之间加⼊了 SSL/TLS 安全协议,使得报⽂能够加密传输。

  • HTTPS 在 TCP 三次握⼿之后,还需进⾏ SSL/TLS 的握⼿过程,才可进⼊加密报⽂传输。HTTPS采⽤对称加密和⾮对称加密结合的【混合加密】⽅式,保证信息的机密性,解决了窃听的⻛险。

  • HTTP 的端⼝号是 80,HTTPS 的端⼝号是 443。

  • HTTPS 协议需要向 CA(证书权威机构) 申请数字证书,来保证服务器的身份是可信的。

什么对称加密?

对称加密也称为私钥加密,使⽤相同的密钥来进⾏加密和解密。

  • 在加密过程中,明⽂数据通过应⽤特定的算法和密钥进⾏加密,⽣成密⽂数据。解密过程则是将密⽂数据应⽤同样的算法和密钥进⾏解密,恢复为明⽂数据。

  • 由于加密和解密都使⽤相同的密钥,因此对称加密算法的速度通常较快,但密钥的安全性很重要。如果密钥泄漏,攻击者可以轻易地解密数据。

什么是非对称加密?

  • ⾮对称加密也称为公钥加密,使⽤⼀对不同但相关的密钥:公钥和私钥。

  • 公钥⽤于加密数据,私钥⽤于解密数据。如果使⽤公钥加密数据,只有拥有相应私钥的⼈才能解密数据;如果使⽤私钥加密数据,可以使⽤相应公钥解密。除了加密和解密,⾮对称加密还⽤于【数字签名】,可以验证消息的来源和完整性。

HTTP1.1 相比于 HTTP1.1 的优点以及存在的缺点?

  • 使用长连接的方式改善了 HTTP/1.0 短连接造成的性能开销。HTTP 1.1起,默认使用长连接 ,默认开启 Connection: keep-alive。 HTTP/1.1的持续连接有非流水线方式和流水线方式 。流水线方式是客户在收到HTTP的响应报文之前就能接着发送新的请求报文。与之相对应的非流水线方式是客户在收到前一个响应后才能发送下一个请求

  • 支持管道(pipeline)网络传输,只要第一个请求发出去了,不必等其回来,就可以发第二个请求出去,可以减少整体的响应时间

  • 在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除

  • 带宽优化及网络连接的使用:HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1则在请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接

  • 如果服务端在处理 A 请求时耗时⽐较⻓,那么后续的请求的处理都会被阻塞住,这称为队头堵塞。所以,HTTP/1.1 管道解决了请求的队头阻塞

存在的缺点:

  • 没有解决响应的队头阻塞,服务器是按请求的顺序响应的,如果服务器响应慢,会招致客户端一直请求不到数据,也就是响应方队头阻塞
  • 头部冗余:每个请求和响应都需要带有⼀定的头部信息,每次互相发送相同的⾸部造成的浪费较多
  • 没有请求优先级控制
  • 请求只能从客户端开始,服务器只能被动响应

HTTP2.0 相比于 HTTP1.1 的优点以及存在的缺点?

  • 头部压缩: HTTP/2 使⽤ HPACK 压缩算法对请求和响应头部进⾏压缩,减少了传输的头部数据量,降低了延迟

  • ⼆进制帧: HTTP/2 将数据分割成⼆进制帧进⾏传输,分为头信息帧(Headers Frame)和数据帧(DataFrame),增加了数据传输的效率

  • 并发传输: 引出了 Stream 概念,多个 Stream 复⽤在⼀条 TCP 连接,针对不同的 HTTP 请求⽤独⼀⽆⼆的 Stream ID 来区分,接收端可以通过 Stream ID 有序组装成 HTTP 消息,不同 Stream 的帧是可以乱序发送的,因此可以并发不同的 Stream ,也就是 HTTP/2 可以并⾏交错地发送请求和响应

  • 服务器推送: 在 HTTP/2 中,服务器可以对客户端的⼀个请求发送多个响应,即服务器可以额外的向客户端推送资源,⽽⽆需客户端明确的请求

存在的缺点:

队头阻塞问题:

HTTP/2 虽然通过多个请求复用一个 TCP 连接解决了 HTTP 的队头阻塞 ,但是一旦发生丢包,就会阻塞住所有的 HTTP 请求,这属于 TCP 层队头阻塞

HTTP/2 是基于 TCP 协议来传输数据的,TCP 是字节流协议,TCP 层必须保证收到的字节数据是完整且连续的,这样内核才会将缓冲区里的数据返回给 HTTP 应用,那么当「前 1 个字节数据」没有到达时,后收到的字节数据只能存放在内核缓冲区里,只有等到这 1 个字节数据到达时,HTTP/2 应用层才能从内核中拿到数据,这就是 HTTP/2 队头阻塞问题

HTTP3.0 相比于 HTTP2.0 的优点以及存在的缺点?

针对 HTTP2.0 TCP层队头阻塞的问题,HTTP3.0中使用了UDP协议代替TCP协议。UDP 发送是不管顺序,也不管丢包的,所以不会出现像 HTTP/2 队头阻塞的问题。大家都知道 UDP 是不可靠传输的,但基于 UDP 的 QUIC 协议 可以实现类似 TCP 的可靠性传输

  • 无队头阻塞,QUIC 协议有自己的一套机制可以保证传输的可靠性的。当某个流发生丢包时,只会阻塞这个流,其他流不会受到影响,因此不存在队头阻塞问题。这与 HTTP/2 不同,HTTP/2 只要某个流中的数据包丢失了,其他流也会因此受影响

  • 支持乱序确认,QUIC 协议使用的 Packet Number 单调递增的设计,可以让数据包不再像TCP 那样必须有序确认,QUIC 支持乱序确认,当数据包Packet N 丢失后,只要有新的已接收数据包确认,当前窗口就会继续向右滑动

  • 更快的连接建立,对于 HTTP/1 和 HTTP/2 协议,TCP 和 TLS 是分层的,分别属于内核实现的传输层、openssl 库实现的表示层,因此它们难以合并在一起,需要分批次来握手,先 TCP 握手,再 TLS 握手。但是 HTTP/3 的 QUIC 协议并不是与 TLS 分层,而是 QUIC 内部包含了 TLS,它在自己的帧会携带 TLS 里的“记录”,再加上 QUIC 使用的是 TLS 1.3,因此仅需 1 个 RTT 就可以「同时」完成建立连接与密钥协商,甚至在第二次连接的时候,应用数据包可以和 QUIC 握手信息(连接信息 + TLS 信息)一起发送,达到 0-RTT 的效果。HTTP/3 在传输数据前虽然需要 QUIC 协议握手,但是这个握手过程只需要 1 RTT,握手的目的是为确认双方的「连接 ID」,连接迁移就是基于连接 ID 实现的。

  • 连接迁移,基于 TCP 传输协议的 HTTP 协议,由于是通过四元组(源 IP、源端口、目的 IP、目的端口)确定一条 TCP 连接。而 QUIC 协议没有用四元组的方式来“绑定”连接,而是通过连接 ID 来标记通信的两个端点,客户端和服务器可以各自选择一组 ID 来标记自己,因此即使移动设备的网络变化后,导致 IP 地址变化了,只要仍保有上下文信息(比如连接 ID、TLS 密钥等),就可以“无缝”地复用原连接,消除重连的成本,没有丝毫卡顿感,达到了连接迁移的功能。

TCP 与 UDP

为什么需要 TIME_WAIT 状态?

主动发起关闭连接的⼀⽅,才会有 TIME-WAIT 状态。

需要 TIME-WAIT 状态,主要是两个原因:

  1. 防⽌历史连接中的数据,被后⾯相同四元组的连接错误的接收;

如果⽹络出现拥塞或延迟,数据包可能会在⽹络中滞留⼀段时间,甚⾄超过了原始连接关闭的时间。如果没有 TIME_WAIT 状态,客户端直接进⼊到 CLOSE 状态,这些滞留的数据包可能会被传递给新连接,导致新连接的数据被旧连接的数据⼲扰。

经过 2MSL 这个时间,⾜以让两个⽅向上的数据包都被丢弃,使得原来连接的数据包在⽹络中都⾃然消失,再出现的数据包⼀定都是新建⽴连接所产⽣的。

  1. 保证「被动关闭连接」的⼀⽅能被正确的关闭,即保证最后的 ACK 能让被动关闭⽅接收,从⽽帮助其正常关闭

如果最后的⼀次ACK报⽂丢失(第四次挥⼿),客户端没有 TIME_WAIT 状态,直接进⼊ClOSE,服务端⼀直在等待ACK状态,⼀直没有等到,就会重发FIN报⽂,⽽客户端已经进⼊到关闭状态,在收到服务端重传的 FIN 报⽂后,就会回 RST 报⽂,服务端收到这个 RST 并将其解释为⼀个错误, 为了防⽌这种情况出现,客户端必须等待⾜够⻓的时间,确保服务端能够收到 ACK,如果服务端没有收到 ACK,那么就会触发 TCP 重传机制,服务端会重新发送⼀个FIN,这样⼀去⼀来刚好两个 MSL 的时间。

为什么 TIME_WAIT 等待的时间是 2MSL?

  1. MSL是 Maximum Segment Lifetime ,报⽂最⼤⽣存时间,它是任何报⽂在⽹络上存在的最⻓时间,超过这个时间报⽂将被丢弃。

  2. 等待MSL两倍:⽹络中可能存在发送⽅的数据包,当这些发送⽅的数据包被接收⽅处理后⼜会向对⽅发送响应,所以⼀来⼀回需要等待 2 倍的时间。

  3. 1 个 MSL 确保四次挥⼿中主动关闭⽅最后的 ACK 报⽂最终能达到对端;1 个 MSL 确保对端没有收到 ACK 重传的 FIN 报⽂可以到达。

  4. 2MSL 的时间是从客户端接收到 FIN 后发送 ACK 开始计时的。如果在 TIME-WAIT 时间内,因为客户端的 ACK没有传输到服务端,客户端⼜接收到了服务端重发的 FIN 报⽂,那么 2MSL 时间将重新计时

TIME_WAIT 过多有什么危害?

过多的 TIME-WAIT 状态主要的危害有两种:一是会占用内存资源;二是占用端口,因为一个TCP连接至少消耗一个本地端口;

  • 如果客户端的 TIME_WAIT 状态过多,占满了所有端⼝资源,则会导致⽆法创建新连接。

  • 如果服务器端的 TIME_WAIT 状态过多,会占用大量的内存资源,没法相应新的连接。

TCP与UDP的区别?

  • 是否面向连接 : UDP 在传送数据之前不需要先建立连接。而 TCP 提供面向连接的服务,在传送数据之前必须先建立连接,数据传送结束后要释放连接。

  • 是否是可靠传输: 远地主机在收到 UDP 报文后,不需要给出任何确认,并且不保证数据不丢失,不保证是否顺序到达。TCP 提供可靠的传输服务,TCP 在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制。通过 TCP 连接传输的数据,无差错、不丢失、不重复、并且按序到达。

  • 是否有状态 : 这个和上面的“是否可靠传输”相对应。TCP 传输是有状态的,这个有状态说的是 TCP 会去记录自己发送消息的状态比如消息是否发送了、是否被接收了等等。为此 ,TCP 需要维持复杂的连接状态表。而 UDP 是无状态服务,简单来说就是不管发出去之后的事情了。

  • 传输效率 : 由于使用 TCP 进行传输的时候多了连接、确认、重传等机制,所以 TCP 的传输效率要比 UDP 低很多。

  • 传输形式 : TCP 是面向字节流的,UDP 是面向报文的。

  • 首部开销 : TCP 首部开销(20 ~ 60 字节)比 UDP 首部开销(8 字节)要大。

  • 是否提供广播或多播服务 : TCP 只支持点对点通信,UDP 支持一对一、一对多、多对一、多对多;

  • UDP 一般用于即时通信,比如: 语音、 视频 、直播等等。这些场景对传输数据的准确性要求不是特别高,比如你看视频即使少个一两帧,实际给人的感觉区别也不大。

  • TCP 用于对传输准确性要求特别高的场景,比如文件传输、发送和接收邮件、远程登录等等。

TCP与UDP的应用场景分别是什么?

  • UDP适⽤于实时传输的场景:UDP适⽤于对数据传输可靠性要求不⾼的场景,如实时游戏、流媒体等,其中实时性⽐数据的准确性更为重要

  • TCP适⽤于可靠数据传输的场景:TCP适⽤于那些对数据传输可靠性要求较⾼的应⽤,如⽂件传输、电⼦邮件、⽹⻚浏览等

TCP如何保证可靠性?

TCP协议保证数据传输可靠性的⽅式主要有:校验和、序列号、确认应答、超时重传、连接管理、流量控制、拥塞控制

  • 序列号和确认应答:TCP通过给每个发送的数据段分配⼀个序列号,以及使⽤确认(ACK)机制来跟踪数据的传输和接收。接收⽅会确认已成功接收的数据,发送⽅则根据收到的确认来确定哪些数据已经被成功传输,以及哪些需要重新发送

  • 超时和重传: TCP使⽤超时机制来检测是否发⽣了数据包的丢失。如果发送⽅在⼀定时间内未收到确认,它会认为数据包丢失,并触发相应的重传。这确保了即使某个数据包在传输过程中丢失,它最终仍能够被成功传递

  • 流量控制: TCP使⽤滑动窗⼝机制来进⾏流量控制,确保发送⽅不会以⾼于接收⽅处理速度的速率发送数据。这有助于防⽌接收⽅缓冲区溢出,并提⾼整个通信链路的效率

  • 拥塞控制: TCP还具有拥塞控制机制,通过动态调整发送速率以适应⽹络状况。当⽹络出现拥塞时,TCP会减缓发送速率,以防⽌进⼀步加剧拥塞

TCP中的元组?

四元组是: 源IP地址、目的IP地址、源端口、目的端口

五元组是: 源IP地址、目的IP地址、协议号、源端口、目的端口

七元组是: 源IP地址、目的IP地址、协议号、源端口、目的端口,服务类型以及接口索引

TCP是怎么保持长链接的?

TCP长连接保持:KeepAlive 。TCP协议的实现里有一个 KeepAlive 机制,自动检测能否和对方连通并保持连接。

保活机制默认是关闭的,TCP连接的任何一方都可打开此功能。有三个主要配置参数用来控制保活功能。

向对端发送一个保活探测报文。

  • 若对端正常存活,且连接有效,对端必然能收到探测报文并进行响应。此时,发送端收到响应报文则证明TCP连接正常,重置保活时间计数器即可。

  • 若由于网络原因或其他原因导致,发送端无法正常收到保活探测报文的响应。那么在一定探测时间间隔(tcp_keepalive_intvl) 后,将继续发送保活探测报文。直到收到对端的响应,或者达到配置的探测循环次数上限(tcp_keepalive_probes) 都没有收到对端响应,这时对端会被认为不可达,TCP连接随存在但已失效,需要将连接做中断处理。

TCP的探活(心跳)是多长时间?

  • 保活时间(tcp_keepalive_time)默认:7200秒

  • 保活时间间隔(tcp_keepalive_intvl)默认:75秒

  • 探测循环次数(tcp_keepalive_probes)默认:9次

也就是默认情况下一条TCP连接在2小时(7200秒)都没有报文交换后,会开始进行保活探测,若再经过9*75秒=11分钟15秒的循环探测都未收到探测响应,即共计:2小时11分钟15秒后会自动断开TCP连接。

和HTTP的 keep-alive 的区别?

http协议是一个运行在TCP协议之上的无状态的应用层协议。它的特点是:客户端的每一次请求都要和服务端创建TCP连接,服务器响应后,断开TCP连接。下次客户端再有请求,则重新建立连接。

在早期的http1.0中,默认就是上述介绍的这种“请求-应答”模式。这种方式频繁的创建连接和销毁连接无疑是有一定性能损耗的。所以引入了keep-alive机制。http1.0默认是关闭的,通过http请求头设置“connection: keep-alive”进行开启;http1.1中默认开启,通过http请求头设置“connection: close”关闭。

keep-alive机制:若开启后,在一次http请求中,服务器进行响应后,不再直接断开TCP连接,而是将TCP连接维持一段时间。在这段时间内,如果同一客户端再次向服务端发起http请求,便可以复用此TCP连接,向服务端发起请求,并重置timeout时间计数器,在接下来一段时间内还可以继续复用。这样无疑省略了反复创建和销毁TCP连接的损耗。

全连接队列和半连接队列有了解吗?

/img/全连接半连接.png

在 TCP 三次握手的时候,Linux 内核会维护两个队列,分别是:

  • 半连接队列,也称 SYN 队列;哈希表
  • 全连接队列,也称 accept 队列;链表

服务端收到客户端发起的 SYN 请求后,内核会把该连接存储到半连接队列,并向客户端响应 SYN+ACK,接着客户端会返回 ACK,服务端收到第三次握手的 ACK 后,内核会把连接从半连接队列移除,然后创建新的完全的连接,并将其添加到 accept 队列,等待进程调用 accept 函数时把连接取出来。

不管是半连接队列还是全连接队列,都有最大长度限制,超过限制时,内核会直接丢弃,或返回 RST 包。默认是丢弃。

使用命名 cat proc/sys/net/ipv4/tcp_abort_on_overflow 查看策略的配置:

  • 0 是表示如果全连接队列满了,那么 server 扔掉 client 发过来的 ack ;
  • 1 是表示如果全连接队列满了,server 发送一个 reset 包给 client,表示废掉这个握手过程和这个连接

那么使用什么命令查看全连接队列的大小呢?

可以使用 ss命令进行查看。使用 ss -help可查看 ss指令的所有功能与用法。

ss -lnt 就是查看正在监听的 TCP socket

1
2
3
wxs-605@hecs-135751:~$ ss -lnt
State                  Recv-Q                 Send-Q                                 Local Address:Port                                 Peer Address:Port                Process                 
LISTEN                 0                      1024                                   127.0.0.53%lo:53                                        0.0.0.0:*                                           

Recv-Q就是当前全连接队列的大小,Send-Q就是全连接队列的最大长度。

同时可使用命令 netstat -s | grep overflowed 来查看全连接队列的溢出次数。

那么使用什么命令查看半连接队列的大小呢?

netstat -natp | grep SYN_RECV | wc -l

同时可使用命令 netstat -s | grep "SYNs to LISTEN" 来查看半连接队列的溢出长度。