写点什么

大厂面试题之计算机网络重点篇 (附答案)

发布于: 2021 年 05 月 20 日

linux 服务器开发相关视频解析:

tcpip,accept,11个状态,细枝末节的秘密,还有哪些你不知道

支撑亿级io的底层基石 epoll实战揭秘


c/c++ linux 服务器开发免费学习地址:c/c++ linux后台服务器高级架构师

一、ISO 七层模型中表示层和会话层功能是什么?

  • 表示层:图像、视频编码解,数据加密。

  • 会话层:建立会话,如 session 认证、断点续传。

二、三次握手四次挥手的变迁图

《TCP/IP 详解 卷 1:协议》有一张 TCP 状态变迁图,很具有代表性,有助于大家理解三次握手和四次挥手的状态变化。如下图所示,粗的实线箭头表示正常的客户端状态变迁,粗的虚线箭头表示正常的服务器状态变迁。


三、对称密钥加密的优点缺点?

对称密钥加密(Symmetric-Key Encryption),加密和解密使用同一密钥。

  • 优点:运算速度快

  • 缺点:无法安全地将密钥传输给通信方

四、非对称密钥加密你了解吗?优缺点?

非对称密钥加密,又称公开密钥加密(Public-Key Encryption),加密和解密使用不同的密钥。

公开密钥所有人都可以获得,通信发送方获得接收方的公开密钥之后,就可以使用公开密钥进行加密,接收方收到通信内容后使用私有密钥解密。

非对称密钥除了用来加密,还可以用来进行签名。因为私有密钥无法被其他人获取,因此通信发送方使用其私有密钥进行签名,通信接收方使用发送方的公开密钥对签名进行解密,就能判断这个签名是否正确。

  • 优点:可以更安全地将公开密钥传输给通信发送方;

  • 缺点:运算速度慢。

五、HTTPS 是什么

HTTPS 并不是新协议,而是让 HTTP 先和 SSL(Secure Sockets Layer)通信,再由 SSL 和 TCP 通信,也就是说 HTTPS 使用了隧道进行通信。通过使用 SSL,HTTPS 具有了加密(防窃听)、认证(防伪装)和完整性保护(防篡改)。

六、HTTP 的缺点有哪些?

  • 使用明文进行通信,内容可能会被窃听;

  • 不验证通信方的身份,通信方的身份有可能遭遇伪装;

  • 无法证明报文的完整性,报文有可能遭篡改。

七、HTTPS 采用的加密方式有哪些?是对称还是非对称?

HTTPS 采用混合的加密机制,使用非对称密钥加密用于传输对称密钥来保证传输过程的安全性,之后使用对称密钥加密进行通信来保证通信过程的效率。


确保传输安全过程(其实就是 rsa 原理):

  1. Client 给出协议版本号、一个客户端生成的随机数(Client random),以及客户端支持的加密方法。

  2. Server 确认双方使用的加密方法,并给出数字证书、以及一个服务器生成的随机数(Server random)。

  3. Client 确认数字证书有效,然后生成呀一个新的随机数(Premaster secret),并使用数字证书中的公钥,加密这个随机数,发给 Server。

  4. Server 使用自己的私钥,获取 Client 发来的随机数(Premaster secret)。

  5. Client 和 Server 根据约定的加密方法,使用前面的三个随机数,生成”对话密钥”(session key),用来加密接下来的整个对话过程。

八、为什么有的时候刷新页面不需要重新建立 SSL 连接?

TCP 连接有的时候会被浏览器和服务端维持一段时间,TCP 不需要重新建立,SSL 自然也会用之前的。

九、SSL 中的认证中的证书是什么?了解过吗?

通过使用 证书 来对通信方进行认证。

数字证书认证机构(CA,Certificate Authority)是客户端与服务器双方都可信赖的第三方机构。

服务器的运营人员向 CA 提出公开密钥的申请,CA 在判明提出申请者的身份之后,会对已申请的公开密钥做数字签名,然后分配这个已签名的公开密钥,并将该公开密钥放入公开密钥证书后绑定在一起。

进行 HTTPS 通信时,服务器会把证书发送给客户端。客户端取得其中的公开密钥之后,先使用数字签名进行验证,如果验证通过,就可以开始通信了。

【文章福利】需要 C/C++ Linux 服务器架构师学习资料加群 812855908(资料包括 C/C++,Linux,golang 技术,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg 等)


十、HTTP 如何禁用缓存?如何确认缓存?

HTTP/1.1 通过 Cache-Control 首部字段来控制缓存。

禁止进行缓存

no-store 指令规定不能对请求或响应的任何一部分进行缓存。

Cache-Control: no-store
复制代码

强制确认缓存

no-cache 指令规定缓存服务器需要先向源服务器验证缓存资源的有效性,只有当缓存资源有效时才能使用该缓存对客户端的请求进行响应。

Cache-Control: no-cache
复制代码

十一、GET 与 POST 传递数据的最大长度能够达到多少呢?

get 是通过 URL 提交数据,因此 GET 可提交的数据量就跟 URL 所能达到的最大长度有直接关系。

很多文章都说 GET 方式提交的数据最多只能是 1024 字节,而实际上,URL 不存在参数上限的问题,HTTP 协议规范也没有对 URL 长度进行限制。

这个限制是特定的浏览器及服务器对它的限制,比如 IE 对 URL 长度的限制是 2083 字节(2K+35 字节)。对于其他浏览器,如 FireFox,Netscape 等,则没有长度限制,这个时候其限制取决于服务器的操作系统;即如果 url 太长,服务器可能会因为安全方面的设置从而拒绝请求或者发生不完整的数据请求。

post 理论上讲是没有大小限制的,HTTP 协议规范也没有进行大小限制,但实际上 post 所能传递的数据量大小取决于服务器的设置和内存大小。

因为我们一般 post 的数据量很少超过 MB 的,所以我们很少能感觉的到 post 的数据量限制,但实际中如果你上传文件的过程中可能会发现这样一个问题,即上传个头比较大的文件到服务器时候,可能上传不上去。

以 php 语言来说,查原因的时候你也许会看到有说 PHP 上传文件涉及到的参数 PHP 默认的上传有限定,一般这个值是 2MB,更改这个值需要更改 php.conf 的 post_max_size 这个值。这就很明白的说明了这个问题了。

十二、网络层常见协议?可以说一下吗?


十三、TCP 四大拥塞控制算法总结?(极其重要)

四大算法

拥塞控制主要是四个算法:1)慢启动,2)拥塞避免,3)拥塞发生,4)快速恢复。这四个算法不是一天都搞出来的,这个四算法的发展经历了很多时间,到今天都还在优化中。

慢热启动算法 – Slow Start

所谓慢启动,也就是 TCP 连接刚建立,一点一点地提速,试探一下网络的承受能力,以免直接扰乱了网络通道的秩序。

慢启动算法:

  1. 连接建好的开始先初始化拥塞窗口 cwnd 大小为 1,表明可以传一个 MSS 大小的数据。

  2. 每当收到一个 ACK,cwnd 大小加一,呈线性上升。

  3. 每当过了一个往返延迟时间 RTT(Round-Trip Time),cwnd 大小直接翻倍,乘以 2,呈指数让升。

  4. 还有一个 ssthresh(slow start threshold),是一个上限,当 cwnd >= ssthresh 时,就会进入“拥塞避免算法”(后面会说这个算法)

拥塞避免算法 – Congestion Avoidance

如同前边说的,当拥塞窗口大小 cwnd 大于等于慢启动阈值 ssthresh 后,就进入拥塞避免算法。算法如下:

  1. 收到一个 ACK,则 cwnd = cwnd + 1 / cwnd

  2. 每当过了一个往返延迟时间 RTT,cwnd 大小加一。

过了慢启动阈值后,拥塞避免算法可以避免窗口增长过快导致窗口拥塞,而是缓慢的增加调整到网络的最佳值。

拥塞发生状态时的算法

一般来说,TCP 拥塞控制默认认为网络丢包是由于网络拥塞导致的,所以一般的 TCP 拥塞控制算法以丢包为网络进入拥塞状态的信号。对于丢包有两种判定方式,一种是超时重传 RTO[Retransmission Timeout]超时,另一个是收到三个重复确认 ACK。

超时重传是 TCP 协议保证数据可靠性的一个重要机制,其原理是在发送一个数据以后就开启一个计时器,在一定时间内如果没有得到发送数据报的 ACK 报文,那么就重新发送数据,直到发送成功为止。

但是如果发送端接收到 3 个以上的重复 ACK,TCP 就意识到数据发生丢失,需要重传。这个机制不需要等到重传定时器超时,所以叫 做快速重传,而快速重传后没有使用慢启动算法,而是拥塞避免算法,所以这又叫做快速恢复算法。

超时重传 RTO[Retransmission Timeout]超时,TCP 会重传数据包。TCP 认为这种情况比较糟糕,反应也比较强烈:

  • 由于发生丢包,将慢启动阈值 ssthresh 设置为当前 cwnd 的一半,即 ssthresh = cwnd / 2.

  • cwnd 重置为 1

  • 进入慢启动过程

最为早期的 TCP Tahoe 算法就只使用上述处理办法,但是由于一丢包就一切重来,导致 cwnd 又重置为 1,十分不利于网络数据的稳定传递。

所以,TCP Reno 算法进行了优化。当收到三个重复确认 ACK 时,TCP 开启快速重传 Fast Retransmit 算法,而不用等到 RTO 超时再进行重传:

  • cwnd 大小缩小为当前的一半

  • ssthresh 设置为缩小后的 cwnd 大小

  • 然后进入快速恢复算法 Fast Recovery。


快速恢复算法 – Fast Recovery

TCP Tahoe 是早期的算法,所以没有快速恢复算法,而 Reno 算法有。在进入快速恢复之前,cwnd 和 ssthresh 已经被更改为原有 cwnd 的一半。快速恢复算法的逻辑如下:

  • cwnd = cwnd + 3 MSS,加 3 MSS 的原因是因为收到 3 个重复的 ACK。

  • 重传 DACKs 指定的数据包。

  • 如果再收到 DACKs,那么 cwnd 大小增加一。

  • 如果收到新的 ACK,表明重传的包成功了,那么退出快速恢复算法。将 cwnd 设置为 ssthresh,然后进入拥塞避免算法。

如图所示,第五个包发生了丢失,所以导致接收方接收到三次重复 ACK,也就是 ACK5。所以将 ssthresh 设置当当时 cwnd 的一半,也就是 6/2 = 3,cwnd 设置为 3 + 3 = 6。然后重传第五个包。当收到新的 ACK 时,也就是 ACK11,则退出快速恢复阶段,将 cwnd 重新设置为当前的 ssthresh,也就是 3,然后进入拥塞避免算法阶段。

十四、为何快速重传是选择 3 次 ACK?

主要的考虑还是要区分包的丢失是由于链路故障还是乱序等其他因素引发。

两次 duplicated ACK 时很可能是乱序造成的!三次 duplicated ACK 时很可能是丢包造成的!四次 duplicated ACK 更更更可能是丢包造成的,但是这样的响应策略太慢。丢包肯定会造成三次 duplicated ACK!综上是选择收到三个重复确认时窗口减半效果最好,这是实践经验。

在没有 fast retransmit / recovery 算法之前,重传依靠发送方的 retransmit timeout,就是在 timeout 内如果没有接收到对方的 ACK,默认包丢了,发送方就重传,包的丢失原因

1)包 checksum 出错

2)网络拥塞

3)网络断,包括路由重收敛,但是发送方无法判断是哪一种情况,于是采用最笨的办法,就是将自己的发送速率减半,即 CWND 减为 1/2,这样的方法对 2 是有效的,可以缓解网络拥塞,3 则无所谓,反正网络断了,无论发快发慢都会被丢;但对于 1 来说,丢包是因为偶尔的出错引起,一丢包就对半减速不合理。

于是有了 fast retransmit 算法,基于在反向还可以接收到 ACK,可以认为网络并没有断,否则也接收不到 ACK,如果在 timeout 时间内没有接收到> 2 的 duplicated ACK,则概率大事件为乱序,乱序无需重传,接收方会进行排序工作;

而如果接收到三个或三个以上的 duplicated ACK,则大概率是丢包,可以逻辑推理,发送方可以接收 ACK,则网络是通的,可能是 1、2 造成的,先不降速,重传一次,如果接收到正确的 ACK,则一切 OK,流速依然(包出错被丢)。

而如果依然接收到 duplicated ACK,则认为是网络拥塞造成的,此时降速则比较合理。

十五、对于 FIN_WAIT_2,CLOSE_WAIT 状态和 TIME_WAIT 状态?你知道多少?

FIN_WAIT_2:

  • 半关闭状态。

  • 发送断开请求一方还有接收数据能力,但已经没有发送数据能力。

CLOSE_WAIT 状态:

  • 被动关闭连接一方接收到 FIN 包会立即回应 ACK 包表示已接收到断开请求。

  • 被动关闭连接一方如果还有剩余数据要发送就会进入 CLOSED_WAIT 状态。

TIME_WAIT 状态:

  • 又叫 2MSL 等待状态。

  • 如果客户端直接进入 CLOSED 状态,如果服务端没有接收到最后一次 ACK 包会在超时之后重新再发 FIN 包,此时因为客户端已经 CLOSED,所以服务端就不会收到 ACK 而是收到 RST。所以 TIME_WAIT 状态目的是防止最后一次握手数据没有到达对方而触发重传 FIN 准备的。

  • 在 2MSL 时间内,同一个 socket 不能再被使用,否则有可能会和旧连接数据混淆(如果新连接和旧连接的 socket 相同的话)。

十六、你了解流量控制原理吗?

目的是接收方通过 TCP 头窗口字段告知发送方本方可接收的最大数据量,用以解决发送速率过快导致接收方不能接收的问题。所以流量控制是点对点控制。

TCP 是双工协议,双方可以同时通信,所以发送方接收方各自维护一个发送窗和接收窗。

  • 发送窗:用来限制发送方可以发送的数据大小,其中发送窗口的大小由接收端返回的 TCP 报文段中窗口字段来控制,接收方通过此字段告知发送方自己的缓冲(受系统、硬件等限制)大小。

  • 接收窗:用来标记可以接收的数据大小。

TCP 是流数据,发送出去的数据流可以被分为以下四部分:已发送且被确认部分 | 已发送未被确认部分 | 未发送但可发送部分 | 不可发送部分,其中发送窗 = 已发送未确认部分 + 未发但可发送部分。接收到的数据流可分为:已接收 | 未接收但准备接收 | 未接收不准备接收。接收窗 = 未接收但准备接收部分。

发送窗内数据只有当接收到接收端某段发送数据的 ACK 响应时才移动发送窗,左边缘紧贴刚被确认的数据。接收窗也只有接收到数据且最左侧连续时才移动接收窗口。

十七、建立 TCP 服务器的各个系统调用过程是怎样的?



服务器:

  • fd:accept 返回的连接描述字,每个连接有一个,生命周期为连接周期。

  • 注:sockfd 是监听描述字,一个服务器只有一个,用于监听是否有连接;fd 是连接描述字,用于每个连接的操作。

  • fd:连接描述字。

  • buf:缓冲区 buf。

  • count:缓冲区长度。

  • 注:大于 0 表示读取的字节数,返回 0 表示文件读取结束,小于 0 表示发生错误。

  • sockfd:服务器 socket 描述字。

  • addr:指向地址结构指针。

  • addrlen:协议地址长度。

  • 注:一旦 accept 某个客户机请求成功将返回一个全新的描述符用于标识具体客户的 TCP 连接。

  • sockfd:要监听的 sock 描述字。

  • backlog:socket 可以排队的最大连接数。

  • sockfd:socket 返回的套接字描述符,类似于文件描述符 fd。

  • addr:有个 sockaddr 类型数据的指针,指向的是被绑定结构变量。

  • addrlen:地址长度。

  • domain:协议域,决定了 socket 的地址类型,IPv4 为 AF_INET。

  • type:指定 socket 类型,SOCK_STREAM 为 TCP 连接。

  • protocol:指定协议。IPPROTO_TCP 表示 TCP 协议,为 0 时自动选择 type 默认协议。

  • 创建 socket -> int socket(int domain, int type, int protocol);

  • 绑定 socket 和端口号 -> int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

    // IPv4的sockaddr地址结构    struct sockaddr_in {        sa_family_t sin_family;    // 协议类型,AF_INET        in_port_t sin_port;    // 端口号        struct in_addr sin_addr;    // IP地址    };    struct in_addr {        uint32_t s_addr;    }
复制代码
  • 监听端口号 -> int listen(int sockfd, int backlog);

  • 接收用户请求 -> int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

  • 从 socket 中读取字符 -> ssize_t read(int fd, void *buf, size_t count);

  • 关闭 socket -> int close(int fd);

客户机:

  • fd:同服务器端 fd。

  • fd、buf、count:同 read 中意义。

  • 大于 0 表示写了部分或全部数据,小于 0 表示出错。

  • sockfd 客户端的 sock 描述字。

  • addr:服务器的地址。

  • addrlen:socket 地址长度。

  • 创建 socket -> int socket(int domain, int type, int protocol);

  • 连接指定计算机 -> int connect(int sockfd, struct sockaddr* addr, socklen_t addrlen);

  • 向 socket 写入信息 -> ssize_t write(int fd, const void *buf, size_t count);

  • 关闭 oscket -> int close(int fd);

十八、TCP 协议如何保证可靠传输?

第一种回答

  • 确认和重传:接收方收到报文就会确认,发送方发送一段时间后没有收到确认就会重传。

  • 数据校验:TCP 报文头有校验和,用于校验报文是否损坏。

  • 数据合理分片和排序:tcp 会按最大传输单元(MTU)合理分片,接收方会缓存未按序到达的数据,重新排序后交给应用层。而 UDP:IP 数据报大于 1500 字节,大于 MTU。这个时候发送方的 IP 层就需要分片,把数据报分成若干片,是的每一片都小于 MTU。而接收方 IP 层则需要进行数据报的重组。由于 UDP 的特性,某一片数据丢失时,接收方便无法重组数据报,导致丢弃整个 UDP 数据报。

  • 流量控制:当接收方来不及处理发送方的数据,能通过滑动窗口,提示发送方降低发送的速率,防止包丢失。

  • 拥塞控制:当网络拥塞时,通过拥塞窗口,减少数据的发送,防止包丢失。

第二种回答

  • 建立连接(标志位):通信前确认通信实体存在。

  • 序号机制(序号、确认号):确保了数据是按序、完整到达。

  • 数据校验(校验和):CRC 校验全部数据。

  • 超时重传(定时器):保证因链路故障未能到达数据能够被多次重发。

  • 窗口机制(窗口):提供流量控制,避免过量发送。

  • 拥塞控制:同上。

第三种回答

首部校验这个校验机制能够确保数据传输不会出错吗?答案是不能。

原因

TCP 协议中规定,TCP 的首部字段中有一个字段是校验和,发送方将伪首部、TCP 首部、TCP 数据使用累加和校验的方式计算出一个数字,然后存放在首部的校验和字段里,接收者收到 TCP 包后重复这个过程,然后将计算出的校验和和接收到的首部中的校验和比较,如果不一致则说明数据在传输过程中出错。

这就是 TCP 的数据校验机制。但是这个机制能够保证检查出一切错误吗?显然不能。

因为这种校验方式是累加和,也就是将一系列的数字(TCP 协议规定的是数据中的每 16 个比特位数据作为一个数字)求和后取末位。但是小学生都知道 A+B=B+A,假如在传输的过程中有前后两个 16 比特位的数据前后颠倒了(至于为什么这么巧合?我不知道,也许路由器有 bug?也许是宇宙中的高能粒子击中了电缆?反正这个事情的概率不为零,就有可能会发生),那么校验和的计算结果和颠倒之前是一样的,那么接收端肯定无法检查出这是错误的数据。

解决方案

传输之前先使用 MD5 加密数据获得摘要,跟数据一起发送到服务端,服务端接收之后对数据也进行 MD5 加密,如果加密结果和摘要一致,则认为没有问题

十九、UDP 是什么

提供无连接的,尽最大努力的数据传输服务(不保证数据传输的可靠性)。

二十、TCP 和 UDP 的区别

1、TCP 面向连接(如打电话要先拨号建立连接);UDP 是无连接的,即发送数据之前不需要建立连接

2、TCP 提供可靠的服务。也就是说,通过 TCP 连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP 尽最大努力交付,即不保证可靠交付

3、TCP 面向字节流,实际上是 TCP 把数据看成一连串无结构的字节流;UDP 是面向报文的

UDP 没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如 IP 电话,实时视频会议等)

4、每一条 TCP 连接只能是点到点的;UDP 支持一对一,一对多,多对一和多对多的交互通信

5、TCP 首部开销 20 字节;UDP 的首部开销小,只有 8 个字节

6、TCP 的逻辑通信信道是全双工的可靠信道,UDP 则是不可靠信道

7、UDP 是面向报文的,发送方的 UDP 对应用层交下来的报文,不合并,不拆分,只是在其上面加上首部后就交给了下面的网络层,论应用层交给 UDP 多长的报文,它统统发送,一次发送一个。而对接收方,接到后直接去除首部,交给上面的应用层就完成任务了。因此,它需要应用层控制报文的大小

TCP 是面向字节流的,它把上面应用层交下来的数据看成无结构的字节流会发送,可以想象成流水形式的,发送方 TCP 会将数据放入“蓄水池”(缓存区),等到可以发送的时候就发送,不能发送就等着 TCP 会根据当前网络的拥塞状态来确定每个报文段的大小。

二十一、UDP 的特点有哪些(附赠 TCP 的特点)?

  • UDP 是无连接的;

  • UDP 使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的链接状态(这里面有许多参数);

  • UDP 是面向报文的;

  • UDP 没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如 IP 电话,实时视频会议等);

  • UDP 支持一对一、一对多、多对一和多对多的交互通信;

  • UDP 的首部开销小,只有 8 个字节,比 TCP 的 20 个字节的首部要短。

那么,再说一次 TCP 的特点:

  • TCP 是面向连接的。(就好像打电话一样,通话前需要先拨号建立连接,通话结束后要挂机释放连接);

  • 每一条 TCP 连接只能有两个端点,每一条 TCP 连接只能是点对点的(一对一);

  • TCP 提供可靠交付的服务。通过 TCP 连接传送的数据,无差错、不丢失、不重复、并且按序到达;

  • TCP 提供全双工通信。TCP 允许通信双方的应用进程在任何时候都能发送数据。TCP 连接的两端都设有发送缓存和接收缓存,用来临时存放双方通信的数据;

  • 面向字节流。TCP 中的“流”(stream)指的是流入进程或从进程流出的字节序列。“面向字节流”的含义是:虽然应用程序和 TCP 的交互是一次一个数据块(大小不等),但 TCP 把应用程序交下来的数据仅仅看成是一连串的无结构的字节流。

二十二、TCP 对应的应用层协议

FTP:定义了文件传输协议,使用 21 端口. Telnet:它是一种用于远程登陆的端口,23 端口 SMTP:定义了简单邮件传送协议,服务器开放的是 25 号端口。POP3:它是和 SMTP 对应,POP3 用于接收邮件。

二十三、UDP 对应的应用层协议

DNS:用于域名解析服务,用的是 53 号端口 SNMP:简单网络管理协议,使用 161 号端口 TFTP(Trival File Transfer Protocal):简单文件传输协议,69

二十四、数据链路层常见协议?可以说一下吗?


二十五、Ping 命令基于哪一层协议的原理是什么?

ping 命令基于网络层的命令,是基于 ICMP 协议工作的。

二十六、在进行 UDP 编程的时候,一次发送多少 bytes 好?

当然,这个没有唯一答案,相对于不同的系统,不同的要求,其得到的答案是不一样的。

我这里仅对像 ICQ 一类的发送聊天消息的情况作分析,对于其他情况,你或许也能得到一点帮助:首先,我们知道,TCP/IP 通常被认为是一个四层协议系统,包括链路层,网络层,运输层,应用层.UDP 属于运输层,

下面我们由下至上一步一步来看:以太网(Ethernet)数据帧的长度必须在 46-1500 字节之间,这是由以太网的物理特性决定的.这个 1500 字节被称为链路层的 MTU(最大传输单元).但这并不是指链路层的长度被限制在 1500 字节,其实这这个 MTU 指的是链路层的数据区.并不包括链路层的首部和尾部的 18 个字节.

所以,事实上,这个 1500 字节就是网络层 IP 数据报的长度限制。因为 IP 数据报的首部为 20 字节,所以 IP 数据报的数据区长度最大为 1480 字节.而这个 1480 字节就是用来放 TCP 传来的 TCP 报文段或 UDP 传来的 UDP 数据报的.又因为 UDP 数据报的首部 8 字节,所以 UDP 数据报的数据区最大长度为 1472 字节.这个 1472 字节就是我们可以使用的字节数。

当我们发送的 UDP 数据大于 1472 的时候会怎样呢?这也就是说 IP 数据报大于 1500 字节,大于 MTU.这个时候发送方 IP 层就需要分片(fragmentation). 把数据报分成若干片,使每一片都小于 MTU.而接收方 IP 层则需要进行数据报的重组. 这样就会多做许多事情,而更严重的是,由于 UDP 的特性,当某一片数据传送中丢失时,接收方便 无法重组数据报.将导致丢弃整个 UDP 数据报。

因此,在普通的局域网环境下,我建议将 UDP 的数据控制在 1472 字节以下为好.

进行 Internet 编程时则不同,因为 Internet 上的路由器可能会将 MTU 设为不同的值. 如果我们假定 MTU 为 1500 来发送数据的,而途经的某个网络的 MTU 值小于 1500 字节,那么系统将会使用一系列的机 制来调整 MTU 值,使数据报能够顺利到达目的地,这样就会做许多不必要的操作.

鉴于 Internet 上的标准 MTU 值为 576 字节,所以我建议在进行 Internet 的 UDP 编程时. 最好将 UDP 的数据长度控件在 548 字节(576-8-20)以内

二十七、TCP 利用滑动窗口实现流量控制的机制?

“流量控制是为了控制发送方发送速率,保证接收方来得及接收。TCP 利用滑动窗口实现流量控制。

TCP 中采用滑动窗口来进行传输控制,滑动窗口的大小意味着接收方还有多大的缓冲区可以用于接收数据。发送方可以通过滑动窗口的大小来确定应该发送多少字节的数据。当滑动窗口为 0 时,发送方一般不能再发送数据报,但有两种情况除外,一种情况是可以发送紧急数据。

“例如,允许用户终止在远端机上的运行进程。另一种情况是发送方可以发送一个 1 字节的数据报来通知接收方重新声明它希望接收的下一字节及发送方的滑动窗口大小。

二十八、可以解释一下 RTO,RTT 和超时重传分别是什么吗?

  • 超时重传:发送端发送报文后若长时间未收到确认的报文则需要重发该报文。可能有以下几种情况:发送的数据没能到达接收端,所以对方没有响应。接收端接收到数据,但是 ACK 报文在返回过程中丢失。接收端拒绝或丢弃数据。

  • RTO:从上一次发送数据,因为长期没有收到 ACK 响应,到下一次重发之间的时间。就是重传间隔。通常每次重传 RTO 是前一次重传间隔的两倍,计量单位通常是 RTT。例:1RTT,2RTT,4RTT,8RTT......重传次数到达上限之后停止重传。

  • RTT:数据从发送到接收到对方响应之间的时间间隔,即数据报在网络中一个往返用时。大小不稳定。

二十九、XSS 攻击是什么?(低频)

跨站点脚本攻击,指攻击者通过篡改网页,嵌入恶意脚本程序,在用户浏览网页时,控制用户浏览器进行恶意操作的一种攻击方式。如何防范 XSS 攻击 1)前端,服务端,同时需要字符串输入的长度限制。2)前端,服务端,同时需要对 HTML 转义处理。将其中的”<”,”>”等特殊字符进行转义编码。防 XSS 的核心是必须对输入的数据做过滤处理。

三十、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。

1)验证请求来源地址;

2)关键操作添加验证码;

3)在请求地址添加 token 并验证。

三十一、文件上传漏洞是如何发生的?你有经历过吗?

文件上传漏洞,指的是用户上传一个可执行的脚本文件,并通过此脚本文件获得了执行服务端命令的能力。许多第三方框架、服务,都曾经被爆出文件上传漏洞,比如很早之前的 Struts2,以及富文本编辑器等等,可被攻击者上传恶意代码,有可能服务端就被人黑了。

如何防范文件上传漏洞?

文件上传的目录设置为不可执行。

1)判断文件类型。在判断文件类型的时候,可以结合使用 MIME Type,后缀检查等方式。因为对于上传文件,不能简单地通过后缀名称来判断文件的类型,因为攻击者可以将可执行文件的后缀名称改为图片或其他后缀类型,诱导用户执行。2)对上传的文件类型进行白名单校验,只允许上传可靠类型。

3)上传的文件需要进行重新命名,使攻击者无法猜想上传文件的访问路径,将极大地增加攻击成本,同时向 shell.php.rar.ara 这种文件,因为重命名而无法成功实施攻击。

4)限制上传文件的大小。

5)单独设置文件服务器的域名。

三十二、拥塞控制原理听说过吗?

  • 拥塞控制目的是防止数据被过多注网络中导致网络资源(路由器、交换机等)过载。因为拥塞控制涉及网络链路全局,所以属于全局控制。控制拥塞使用拥塞窗口。

  • TCP 拥塞控制算法:慢开始 & 拥塞避免:先试探网络拥塞程度再逐渐增大拥塞窗口。每次收到确认后拥塞窗口翻倍,直到达到阀值 ssthresh,这部分是慢开始过程。达到阀值后每次以一个 MSS 为单位增长拥塞窗口大小,当发生拥塞(超时未收到确认),将阀值减为原先一半,继续执行线性增加,这个过程为拥塞避免。快速重传 & 快速恢复:略。最终拥塞窗口会收敛于稳定值。

三十三、如何区分流量控制和拥塞控制?

  • 流量控制属于通信双方协商;拥塞控制涉及通信链路全局。

  • 流量控制需要通信双方各维护一个发送窗、一个接收窗,对任意一方,接收窗大小由自身决定,发送窗大小由接收方响应的 TCP 报文段中窗口值确定;拥塞控制的拥塞窗口大小变化由试探性发送一定数据量数据探查网络状况后而自适应调整。

  • 实际最终发送窗口 = min{流控发送窗口,拥塞窗口}。

三十四、常见的 HTTP 状态码有哪些?


1xx 信息

100 Continue :表明到目前为止都很正常,客户端可以继续发送请求或者忽略这个响应。

2xx 成功

  • 200 OK

  • 204 No Content :请求已经成功处理,但是返回的响应报文不包含实体的主体部分。一般在只需要从客户端往服务器发送信息,而不需要返回数据时使用。

  • 206 Partial Content :表示客户端进行了范围请求,响应报文包含由 Content-Range 指定范围的实体内容。

3xx 重定向

  • 301 Moved Permanently :永久性重定向

  • 302 Found :临时性重定向

  • 303 See Other :和 302 有着相同的功能,但是 303 明确要求客户端应该采用 GET 方法获取资源。

  • 304 Not Modified :如果请求报文首部包含一些条件,例如:If-Match,If-Modified-Since,If-None-Match,If-Range,If-Unmodified-Since,如果不满足条件,则服务器会返回 304 状态码。

  • 307 Temporary Redirect :临时重定向,与 302 的含义类似,但是 307 要求浏览器不会把重定向请求的 POST 方法改成 GET 方法。

4xx 客户端错误

  • 400 Bad Request :请求报文中存在语法错误。

  • 401 Unauthorized :该状态码表示发送的请求需要有认证信息(BASIC 认证、DIGEST 认证)。如果之前已进行过一次请求,则表示用户认证失败。

  • 403 Forbidden :请求被拒绝。

  • 404 Not Found

5xx 服务器错误

  • 500 Internal Server Error :服务器正在执行请求时发生错误。

  • 503 Service Unavailable :服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。

用户头像

还未添加个人签名 2020.11.26 加入

C/C++linux服务器开发群 812855908

评论

发布
暂无评论
大厂面试题之计算机网络重点篇(附答案)