2.6 网络面试问题

server/2024/12/23 6:09:50/

tcp 与 udp的区别

1.tcp 是基于连接的  UDP是基于数据包
2.处理并发的方式不通       

        a.tcp用epoll进行监听的

        b. udp是模拟tcp的连接过程,服务端开放一个IP端口,收到连接后,服务端用另一个IP和端口发包给客户端。

3.tcp根据协议MTU黏包及分片 或  默认30ms的延迟发送黏包及分片, 接收端则需要分包,分包有两种分包方案。

tcp分包方案1:可以给包头(用户数据的头)前几个字节(自己定)存放包长,接收端先解析长度,一次性接收整包长度后再接收下一包。

tcp分包方案2:包的末尾可以加分割符 ,比如\r\n\r\n, 检索分隔符以确认分包的位置。

tcp 的两种方案都是基于tcp的有序接收来处理的。

udp是无序的,发送端没有黏包。每包的最大长度就是MTU的值。如果接收端需要有序接收则需要发送端给每个包编上号码,接收端则重新排序。

4.使用场景不同 tcp因为有延迟确认,注定了tcp无法应用到快速响应场景中,游戏,直播。UDP则可以
5.tcp适合长连接,因为有握手和挥手。udp适合短连接,一次发送 一次响应的那种,比如DNS请求

DNS 请求报文通常使用 UDP 协议,并且使用端口号 53。UDP 协议适用于 DNS 因为它简单且开销低,适合快速的请求和响应场景。

但在某些情况下,DNS 也会使用 TCP 协议

  1. 响应数据大于 512 字节:如果 DNS 响应的内容较多(如包含许多记录或 DNSSEC 数据),UDP 数据包无法容纳,客户端会通过 TCP 重新请求。
  2. 区域传送 (Zone Transfer):区域传送(如在主从 DNS 服务器之间同步区域数据)使用 TCP 协议。
  3. EDNS(扩展 DNS):启用 EDNS 后,UDP 包的大小上限可以增加,但如果数据依然超出,仍然会切换到 TCP。

总结来说,常规 DNS 查询使用 UDP大数据或特殊情况切换到 TCP

MTU的讨论

----------------------------------------------------------------------------------------------

MTU(Maximum Transmission Unit,最大传输单元)限制的是网络数据帧中 有效负载(payload) 的最大字节长度,即 IP 数据包中的数据部分的最大大小

通常,MTU 的限制包括以下内容:

  • IP 层数据:对于 IPv4 网络,标准的以太网 MTU 为 1500 字节,这表示 IP 数据包的最大大小(包括 IP 头部和数据部分)不能超过 1500 字节。
  • 链路层帧:以太网帧的总大小会包含以太网头部(通常为 14 字节)和 CRC 校验部分(通常为 4 字节),因此,最终传输的以太网帧总长度为 1500 + 14 + 4 = 1518 字节(如果启用了 VLAN,额外增加 4 字节)。

MTU 限制的关键点

  • 应用层数据:在传输时会被拆分成更小的 IP 数据包片段,以适应 MTU 限制。
  • IP 分片:如果数据包大于 MTU,会在传输时分片。

-------------------------------------------------------------------------------------------

在已知 MTU 的情况下,TCP 和 UDP 的 IP 头部长度、TCP/UDP 头部长度都是固定的,因此可以计算出用户负载(payload)的数据长度。

具体计算方法

假设标准的以太网 MTU 为 1500 字节,并且我们在 IPv4 环境下:

1. IP 头部

  • IPv4 头部长度:通常为 20 字节(无选项字段时)。
  • IPv6 头部长度:固定为 40 字节(无选项字段时)。

2. TCP 和 UDP 头部

  • TCP 头部长度:通常为 20 字节(无选项字段时)。
  • UDP 头部长度:固定为 8 字节。

计算用户负载长度

1. TCP 数据包的有效负载(以 IPv4 为例)

  • 总 MTU 为 1500 字节。
  • 减去 IP 头部(20 字节)和 TCP 头部(20 字节): 1500−20−20=1460 字节1500 - 20 - 20 = 1460 \text{ 字节}1500−20−20=1460 字节
  • 因此,对于标准的 IPv4 TCP 包,用户数据的最大长度是 1460 字节

2. UDP 数据包的有效负载(以 IPv4 为例)

  • 总 MTU 为 1500 字节。
  • 减去 IP 头部(20 字节)和 UDP 头部(8 字节): 1500−20−8=1472 字节1500 - 20 - 8 = 1472 \text{ 字节}1500−20−8=1472 字节
  • 因此,对于标准的 IPv4 UDP 包,用户数据的最大长度是 1472 字节

结果总结

在 IPv4 环境下:

  • TCP:用户数据最大为 1460 字节
  • UDP:用户数据最大为 1472 字节

这种计算方式依赖于默认的头部大小,如果有其他选项字段(如 IP 选项、TCP 选项),则用户数据的最大长度会相应减少。

IP头和TCP的选项字段一般都有可能是什么

在 IP 和 TCP 协议中,选项字段是可选的附加字段,通常用于扩展功能或优化网络性能。以下是 IP 和 TCP 中常见的选项字段:

1. IP 头部选项字段

IP 头部选项字段通常在 IPv4 中使用较多,IPv6 则使用扩展头来处理类似功能。IPv4 的 IP 头部选项字段的最大长度是 40 字节,一般包括以下内容:

  • 记录路由 (Record Route, RR):记录数据包在经过的路由器的 IP 地址,以帮助网络诊断和追踪路径。通常限制最多记录 9 个路由器地址。
  • 时间戳 (Timestamp):记录数据包经过的每个路由器的时间戳,用于网络时延测量。
  • 松散源路由 (Loose Source Routing, LSR):允许发送方指定数据包经过的部分路由节点,其他节点则由路由器自动选择。该选项有助于绕过拥塞路由,但较少使用。
  • 严格源路由 (Strict Source Routing, SSR):要求数据包必须严格按照指定的路由节点传输,不允许自动选择其他路径。
  • 安全 (Security):用于标记数据包的安全级别,适用于军事或其他高安全要求的环境,但在实际网络中应用较少。

2. TCP 头部选项字段

TCP 头部选项字段主要用于优化传输性能,通常 TCP 头部选项的最大长度是 40 字节。以下是常见的 TCP 选项:

  • 最大段大小 (Maximum Segment Size, MSS):由客户端和服务器在建立连接时交换,表示每个 TCP 段的最大数据负载大小,常用于避免 IP 分片。
  • 窗口缩放 (Window Scale):允许 TCP 窗口大小扩大,以支持更大的窗口,优化高带宽、高延迟的网络传输。
  • 选择性确认 (Selective Acknowledgment, SACK):允许接收方确认非连续接收到的数据段,优化丢包恢复,减少重传的数据量。
  • 时间戳 (Timestamp):用于 RTT(Round Trip Time)计算,帮助更精准地管理数据传输时间,并有助于防止旧数据包重传引起的干扰(防止重播攻击)。
  • NOP(No Operation):填充选项,不执行操作,通常用于对齐字段,确保其他选项按 4 字节对齐。
  • 快速打开 (TCP Fast Open, TFO):通过保存加密的 Cookie 进行快速的 TCP 连接重用,减少三次握手延迟,提升传输效率。

总结

  • IP 头选项字段:主要用于网络路径跟踪、路由控制和安全标记,虽然具备强大功能,但实际应用较少。
  • TCP 头选项字段:广泛用于优化传输,特别是在现代网络中,MSS、窗口缩放和 SACK 是最常见的选项。

MTU的值在哪修改

在操作系统中,可以通过命令来修改网络接口的 MTU 值。不同系统的修改方式略有差异,以下是常见方法:

### 1. **Linux**

在 Linux 上,可以使用 `ip` 或 `ifconfig` 命令来修改 MTU 值。

- 使用 `ip` 命令:

  ```bash

  sudo ip link set dev <interface> mtu <value>

  例如,设置 `eth0` 接口的 MTU 为 1400 字节:

  ```bash

  sudo ip link set dev eth0 mtu 1400

- 使用 `ifconfig` 命令:

  ```bash

  sudo ifconfig <interface> mtu <value> up

  ```

  例如:

  ```bash

  sudo ifconfig eth0 mtu 1400 up

  ```

### 2. **Windows**

在 Windows 上,可以通过 `netsh` 命令修改 MTU 值:

- 打开命令提示符或 PowerShell(以管理员身份运行),然后输入以下命令:

  ```powershell

  netsh interface ipv4 set subinterface "<interface_name>" mtu=<value> store=persistent

  ```

  例如,将接口名为 `Ethernet` 的 MTU 设置为 1400:

  ```powershell

  netsh interface ipv4 set subinterface "Ethernet" mtu=1400 store=persistent

  ```

### 3. **macOS**

在 macOS 上,可以使用 `ifconfig` 命令:

  ```bash

  sudo ifconfig <interface> mtu <value>

  ```

  例如,设置 `en0` 接口的 MTU 为 1400:

  ```bash

  sudo ifconfig en0 mtu 1400

  ```

### 4. **路由器**

在路由器上,MTU 设置通常在 **管理界面**的网络接口或 WAN 设置中。不同的路由器管理界面略有不同,通常在**高级设置**或**网络设置**中找到 MTU 配置选项。

### 注意事项

- 修改 MTU 值可能会影响网络性能,应根据具体网络环境和需求进行调整。

- 调整 MTU 值后,通常无需重启网络接口,但某些网络配置可能需要重启。

MSS、窗口缩放和 SACK 这几个功能的具体讲解

1. MSS(Maximum Segment Size,最大段大小)

MSS 是 TCP 连接在三次握手过程中由客户端和服务器协商决定的一个参数,它定义了每个 TCP 数据段中用户数据部分(不含 TCP/IP 头部)的最大大小。

  • 工作原理
    • MSS 的值是基于 MTU(最大传输单元)计算得出,通常为 MTU - IP头长度 - TCP头长度。在以太网上,典型 MTU 是 1500 字节,去掉 IP(20 字节)和 TCP 头部(20 字节)后,MSS 通常是 1460 字节。
    • 通过协商 MSS 值,发送方和接收方知道每个数据段最大可以发送多少字节的有效数据,避免了过大的数据段导致 IP 分片,提高了传输效率。
  • 优点
    • 避免了 IP 分片:确保数据段大小不超过路径上的 MTU。
    • 提高传输效率:减少分片的可能性,降低重传的开销。

2. 窗口缩放(Window Scale)

TCP 的窗口缩放是一个选项,用于支持更大的 TCP 窗口大小。它解决了默认 TCP 窗口大小的限制,允许在高带宽、长延迟(高 BDP)网络中更高效地传输数据。

  • 背景
    • TCP 的窗口大小字段默认只能容纳 16 位数值,最大窗口大小为 65535 字节(64 KB)。
    • 在高带宽、长延迟的网络中(如卫星网络或光纤链路),64 KB 的窗口不足以发挥带宽优势。
  • 工作原理
    • 窗口缩放选项在三次握手期间协商,它是一个 8 位值,表示对窗口大小进行的左移位数,最大值为 14。
    • 通过窗口缩放,可以将窗口大小扩大到 65535 * 2^14 = 1 GB,以支持大带宽延迟积 (BDP) 网络
  • 优点
    • 允许更大的窗口大小,提高了数据流传输的效率。
    • 有助于在高带宽、高延迟的网络中充分利用链路。

3. SACK(Selective Acknowledgment,选择性确认)

SACK 是一种数据丢失恢复机制,允许接收方只确认丢失的特定数据段,而非重新传输已成功接收的所有数据段。TCP 默认的确认机制是累计确认(Cumulative Acknowledgment),只能确认所有连续收到的数据。这种方式在数据丢包时会导致大量数据重传,而 SACK 则可以减少这种冗余。

  • 工作原理
    • SACK 在 TCP 头中增加一个选项字段,接收方可以通过该选项告诉发送方哪些数据段已成功接收,哪些数据段丢失。
    • 当发送方收到 SACK 信息后,只重传丢失的数据段,避免重传已成功接收的数据。
  • 优点
    • 减少重传数据量,降低网络负担,尤其在高丢包环境中更为有效。
    • 提高了网络传输的效率和可靠性,加快了丢包恢复速度。

总结

  • MSS:限制每个 TCP 数据段的最大数据大小,避免 IP 分片。
  • 窗口缩放:允许更大窗口大小,以支持高带宽、高延迟网络,充分利用网络资源。
  • SACK:提供精确的丢包信息,减少不必要的重传,提高丢包恢复效率。

这些选项广泛应用于现代 TCP 连接中,尤其在高带宽和高延迟的网络环境中,有效提升了网络的整体传输性能。

窗口缩放的选项段是否会被攻击,假如被人设置为3,则会反复重传?

窗口缩放选项确实存在被攻击的可能性,称为 窗口缩放攻击。在这种攻击中,恶意方可以在 TCP 连接建立过程中篡改或伪造窗口缩放因子,将其设置为较小的值,比如 1 或 3。这样会导致 TCP 发送方的窗口大小严重受限,传输效率大幅降低,甚至可能导致大量的 重传带宽浪费

窗口缩放攻击的具体原理

窗口缩放因子是在 TCP 三次握手期间协商的,因此恶意方可以在这一过程中进行中间人攻击(MITM),将窗口缩放因子修改为非常小的值。这样会导致以下问题:

  1. 窗口大小受限:TCP 窗口大小由 窗口大小 = 初始窗口大小 × 2^缩放因子 计算得到。若缩放因子被恶意设置为 1 或 3,那么窗口大小可能会被限制在很小的范围(例如几 KB),导致数据传输受到严重限制。
  2. 频繁等待和超时:由于窗口大小限制,发送方每次只能发送少量数据,并在接收方确认后才能继续发送。这会导致频繁等待,降低吞吐量,增加 RTT。
  3. 频繁重传:在窗口缩放因子非常小时,发送方在高延迟网络环境中可能会频繁触发超时重传,进一步加剧网络拥塞,影响传输稳定性。

如何防范窗口缩放攻击

  1. 验证三次握手数据:在 TCP 连接建立时,可以通过防火墙或安全网关对三次握手包进行完整性检查,确保窗口缩放因子未被篡改。
  2. 限制最小窗口缩放因子:可以通过网络配置或安全策略,设置一个合理的窗口缩放因子的最小值。例如,设定最小值为 6(窗口扩大到至少 64 KB),避免过小的因子影响性能。
  3. 使用加密协议:通过加密手段(如 TLS)建立安全通道,确保 TCP 三次握手过程中交换的选项字段不易被篡改。
  4. 监测网络性能异常网络设备可以设置监控和告警机制,当发现窗口大小异常小或出现频繁超时重传时,自动触发告警并进一步检查原因。

总结

窗口缩放确实可能被恶意攻击者利用来影响连接性能,但通过加密、网络监控和合理配置,可以有效降低此类攻击的风险。

如何在用户层获取 MSS

对于TCP而言 协议中没有MTU的值的确认,MSS其实就是MTU算出的一个值,一般由内核自己管理。

通过 getsockopt 函数,可以在用户层获得当前 TCP 连接的 MSS 值。这是通过查询套接字的 TCP_MAXSEG 选项来实现的,例如:

#include <stdio.h>

#include <sys/socket.h>

#include <netinet/tcp.h>  // TCP_MAXSEG

#include <arpa/inet.h>

int main() {

    int sock = socket(AF_INET, SOCK_STREAM, 0);

    if (sock < 0) {

        perror("Socket creation failed");

        return -1;

    }

    // 设置服务器地址

    struct sockaddr_in server_addr;

    server_addr.sin_family = AF_INET;

    server_addr.sin_port = htons(80);  // 使用 HTTP 端口

    inet_pton(AF_INET, "192.168.1.1", &server_addr.sin_addr);  // 目标IP

    // 连接服务器

    if (connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {

        perror("Connect failed");

        return -1;

    }

    // 获取 MSS 值

    int mss;

    socklen_t len = sizeof(mss);

    if (getsockopt(sock, IPPROTO_TCP, TCP_MAXSEG, &mss, &len) == 0) {

        printf("MSS value: %d\n", mss);

    } else {

        perror("Failed to get MSS");

    }

    close(sock);

    return 0;

}

为什么 MSS 设置由系统控制

  1. MSS 受路径 MTU 决定:MSS 通常是通过路径上的 MTU 减去 IP 和 TCP 头部长度来自动确定的,防止了路径上数据包被分片,确保传输效率。
  2. 自动调整传输大小:操作系统内核会依据 MSS 值调整 TCP 发送缓冲区的分片大小,确保不会发送超过 MSS 的数据包,从而避免 IP 层的分片处理,提升网络性能。
  3. 用户层应用程序不必担心分片:通过 send 或 write 的数据长度可以任意,但 TCP 会在内核中自动分段,因此用户层应用程序无需直接控制分片过程。

因此,通过 getsockopt 获取 MSS 后,用户层应用程序可以大致控制发送数据的长度,防止接近或超过 MSS,以最大化数据传输效率。


Sign in · GitLab


http://www.ppmy.cn/server/152423.html

相关文章

递归实现指数型枚举(递归)

92. 递归实现指数型枚举 - AcWing题库 每个数有选和不选两种情况 我们把每个数看成每层&#xff0c;可以画出一个递归搜索树 叶子节点就是我们的答案 很容易写出每dfs函数 dfs传入一个u表示层数 当层数大于我们n时&#xff0c;去判断每个数字的选择情况&#xff0c;输出被选…

Python实现应用最小二乘法融合SVM-LSTM回归模型电力负荷预测项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后关注获取。 1.项目背景 随着全球能源需求的不断增长&#xff0c;电力系统的稳定性和效率变得至关重要。准确的电力负荷预测…

web实操8-cookie

会话技术 会话&#xff1a; 一次会话中包含多次请求和响应。 客户端浏览器访问服务器的资源&#xff0c;只要客户端或者服务器端不关闭&#xff0c;这始终在一次会话范围内&#xff0c;这一次会话范围内可以包含多次请求并且收到多次相应。 一次会话&#xff1a;浏览器第一…

POI-TL插件开发-表格分组插件

POI-TL版本&#xff1a;1.12.2 改造于&#xff1a;LoopRowTableRenderPolicy 模板设计&#xff1a; 分组之前&#xff1a; 分组之后&#xff1a; 代码实现&#xff1a; public class LoopRowGroupTableRenderPolicy implements RenderPolicy {private String prefix;privat…

设计模式の命令访问者迭代器模式

文章目录 前言一、命令模式二、访问者模式三、迭代器模式 前言 本篇是关于设计模式中命令模式、访问者模式、以及迭代器模式的学习笔记。 一、命令模式 命令模式是一种行为型设计模式&#xff0c;其核心目的在于将命令的发送者和接受者解耦&#xff0c;提供一个中间层对命令进行…

android recycleview 中倒计时数据错乱

原因 recyceleview 当页面划出屏幕外后&#xff0c;默认会有两条进入缓存区&#xff0c;这些item的结构会被保存&#xff0c;数据被清除&#xff0c;方便其他新进入屏幕的数据复用item&#xff0c;超过两条外的item会进入缓存池被完全销毁重用。 如果我们的页面上有editText 或…

经典系统重塑(sql层)

内容 这个音乐门户网站是我一直在写的一个项目&#xff0c;因为周期较长&#xff0c;虽然功能都给予了大体实现&#xff0c;但是确实无论是sql层面还是业务层面都有很大缺陷。 先看最主要的music表&#xff0c;这music字段指的是音乐地址&#xff0c;名字需要改一下&#xff0…

【批量生成WORD和PDF文件】根据表格内容和模板文件批量创建word文件,一次性生成多个word文档和批量创建PDF文件

如何按照Word模板和表格的数据快速制作5000个word文档 &#xff1f; 在与客户的合作的中需要创建大量的合同&#xff0c;这些合同的模板大概都是一致的&#xff0c;是不是每次我们都需要填充不一样的数据来完成&#xff1f; 今天用表格数据完成合同模板的填充&#xff0c;批量…