【问题标题】:write() and TCP/IP overheadwrite() 和 TCP/IP 开销
【发布时间】:2011-02-14 02:27:43
【问题描述】:

如果我使用 write() 逐字节写入套接字文件描述符,

  • 现在每个字节都是一个数据包吗?
  • 套接字是否会在每个字节中添加 TCP/IP 标头?
  • 或者它是否具有缓冲机制(我个人对此表示怀疑,因为我没有显式刷新)。

例如:

write(fd, 'a', 1);
write(fd, 'b', 1);
write(fd, 'c', 1);

这样会不会比说效率低

write (fd, 'abc', 3);
  • 我必须在这里问这个问题,因为我不具备监控流量中的 TCP/IP 标头的专业知识。谢谢。

【问题讨论】:

    标签: c sockets tcp unistd.h


    【解决方案1】:

    不,不是每个字节都会变成一个数据包。由于 Nagle 算法和其他因素,一些可能会合并。每个数据包会有一个 TCP 标头,而不是每个字节。

    也就是说,您应该避免逐字节调用 write/send,因为每个都是系统调用,这很昂贵(在本地机器上,而不是在网络上的最终结果)。

    【讨论】:

      【解决方案2】:

      添加到 John 的答案中,您可以禁用 Nagle 算法(通过 TCP_NODELAY),然后第一个版本会变慢。

      反过来,您可以调用writev() 而不是write(),这将导致第一个版本与第二个版本完全相同。

      【讨论】:

      • +1 表示writev。您还可以将stdio 与缓冲的FILE 一起使用。
      【解决方案3】:

      这实际上取决于 TCP/IP 堆栈的实现。这实际上取决于操作系统中实现的分段。大多数操作系统已经内置了很多优化。

      如果您正在查看最坏的情况,TCP 标头是 20 字节,IP 标头是 20 字节以及帧标头的大小(取决于您使用的协议,可能是以太网),所以您可以期待加上你的有效载荷。话虽如此,互联网中的大部分流量都由 ACK 主导,但是您的网络堆栈应该结合有效负载。

      【讨论】:

      • 它还依赖于 TCP/IP 规范,该规范默认要求像 Nagle 算法这样的操作。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-21
      相关资源
      最近更新 更多