networking - TCP缓冲区在进程内存的地址空间中吗?

标签 networking tcp linux-kernel network-programming operating-system

我被告知要增加 TCP 缓冲区大小以便更快地处理消息。 我的问题是,无论我为 TCP 消息使用什么缓冲区(ByteBuffer、DirectByteBuffer 等),只要 CPU 从 NIC 接收到中断,以处理读取套接字数据的网络请求,操作系统是否会在地址空间之外的内存中维护任何缓冲区请求进程(即正在监听该套接字的进程)

无论CPU以何种方式接收网络数据,它总是只写入进程地址空间的缓冲区,不维护地址空间之外的缓冲区(包括'Recv-Q'和netstat命令的'Send-Q')为了这次交流?

最佳答案

Linux网络栈接收数据的过程有点复杂。我写了一个comprehensive guide to the Linux network stack这解释了从设备驱动程序到用户态程序的套接字接收队列你需要知道的一切。

内核中有很多地方维护缓冲区:

  1. 数据包到达后由 NIC 写入的 DMA 环。
  2. 对 DMA 环上数据包的引用用于处理数据包。
  3. 最后,如果接收队列未满,则将数据包数据添加到进程的接收队列。
  4. 从套接字读取将从进程的接收队列中提取数据包。
  5. 如果发生数据包嗅探,数据包数据将被复制并发送到由数据包嗅探代码添加的任何过滤器。

上面链接的博文中描述了数据移动、统计和删除(需要时)的完整过程。

现在,如果您想更快地处理消息,我假设您的意思是您想减少数据包处理延迟,对吗?如果是这样,您应该考虑使用 SO_BUSYPOLL这有助于减少数据包处理延迟。

增加接收缓冲区只会增加可以排队等待用户空间套接字的数据包数量。要提高数据包处理能力,您需要仔细监控和调整网络堆栈的每个组件。您可能需要使用 RPS 之类的东西来增加处理数据包的 CPU 数量。

您还需要监控网络堆栈的每个组件,以确保可用缓冲区和 CPU 处理能力足以处理您的数据包工作负载。

关于networking - TCP缓冲区在进程内存的地址空间中吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38735424/

相关文章:

java - 双向连接

网络设置更改后,Linux Debian SSH 连接到另一台机器有延迟

java - 如何切换 ConnectivityManager.getBackgroundDataSetting() 返回的选项?

linux - 如何读取arm linux中的内核镜像?

javascript - 有没有办法检查用户是否可以使用 Javascript 解析某个主机名?

c++ - 在线游戏的 session 通常如何存储?

c++ - 对 WSACleanup() 的错误调用杀死了 WSAStartup()

c++ - 使用Boost ASIO处理无套接字的TCP

c - 隐藏报告描述符 : wrong padding

linux - 用户空间中的 ktime_get() 等价物