【问题标题】:Slow socket's recv on Windows for lots of small messages用于大量小消息的 Windows 上的慢速套接字接收
【发布时间】:2013-08-14 15:28:13
【问题描述】:

我正在使用套接字库 (SOCK_STREAM) 在 Python 中开发小型服务器。服务器应该接收很多小消息(25-40字节),处理它们并尽可能快地转发。

在 Linux 和 OSX 上完美运行,socket 的 recv 函数一到达就返回数据。不幸的是,在 Windows (8 Pro) 上,它似乎在从 recv 函数返回之前累积数据。

我尝试使用 recv 函数限制读取的最大数据量,但这并没有太大帮助。看起来数据是内部积累的。

我必须在服务器(Python)或客户端(Java 的 Socket)中设置任何特定的 Socket 选项吗?

编辑

我的一位同事建议通过填充虚拟数据将每条消息四舍五入到 1KB。 这可能有助于避免@PeterLawrey 指出的内部缓冲区。

我没有机会尝试。您认为它可能有帮助吗?它是有效且被广泛采用的技术?

【问题讨论】:

  • 你使用 TCP 吗?你设置 SO_NODELAY 对吗?否则发送方会缓存数据。
  • 如果他在其他平台上获取数据,这应该不是问题。假设他使用的是同一个发送者,无论服务器在哪里运行。
  • @Joni 我没有在客户端设置任何特定选项,所以我想它默认为 Android 上的标准 Java 选项。在服务器上我只设置了 SO_REUSEADDR。
  • @xaxxon 服务器和客户端的代码在所有平台上都是一样的。
  • 您可以关闭 nagle,但操作系统和网络适配器可以自行合并。我建议使用网络适配器而不是操作系统。

标签: java windows sockets python-2.7


【解决方案1】:

在 Java 程序中操作为套接字保留的内核内存量的方法是设置 SO_RCVBUF(在 C/C++ 程序中,您将使用 setsockopt 来执行此操作)。

我宁愿不在这里复制大量代码,而是给你一些参考。

Documentation of SocketOptions
Documentation of SO_RCVBUF

您可以使用它们来减少内核在将内容返回给您之前将缓冲的数量。

也就是说,如果您的应用程序有 SOCK_STREAM,它不会立即返回任何可用数据,我看不出有任何理由。我认为可能是其他问题。

【讨论】:

  • Server 的代码很简单,就像 while 里面带有 select/recv 一样。客户端的代码使用out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true); 创建输出流。它在每个“消息”写入后刷新。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-24
  • 2016-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多