C# 套接字 : is multiple sending less efficient than a single send?

标签 c# sockets

我正在编写一个为数千个连接提供服务的高吞吐量服务器。假设我有 400 个字节要通过套接字发送。假设我用两种方式来做:

  1. 调用 Socket.Send() 40 次,每次发送 10 个字节。
  2. 调用 Socket.Send() 一次,发送 400 个字节。

这两种方式在速度、CPU负载等方面有很大区别吗?

最佳答案

如果Socket.NoDelay保留为false,那么它很少会产生任何影响 - 大多数时候,你只是要在本地缓冲 - 尽管P/Invoke 开销比绝对必要的多一点(由于通过套接字层进行大量调用)。请注意,在您关心的任何地方,Socket.NoDelay 通常应设置为 true

如果Socket.NoDelaytrue,那么如果一切都最大限度地工作,那么您可能引入额外的使用 40 次发送 10 字节进行数据包分段,这在使用 1 次发送 400 字节时可以避免。然而,在许多情况下,操作系统/硬件堆栈中的各种抽象和层意味着许多 10 字节 block 可能最终会共享数据包。不过,在最佳情况下,这仍然比 1 个数据包多得多。

另请注意,这始终是一种权衡:数据包碎片会降低总体吞吐量,但如果其他 390 字节需要花费较长的时间,那么尽早发送第一个字节可能会减少感知的延迟。可测量(但可能很小)的构建时间。

在大多数情况下:这不太可能成为瓶颈。如果您可以避免数据包碎片而不导致延迟,那么这可能是可取的。如果是我,我可能会更关心高效的缓冲区管理,以最大限度地提高可扩展性,同时避免由于 GC 造成的暂停;像新的“管道”IO API 这样的工具确实可以帮助解决这个问题,并且 Kestrel 可用于托管基于“管道”的 TCP 服务器,其代码比您编写的代码要您自己的套接字监听器 - 然后它会为您处理所有缓冲区管理。

关于C# 套接字 : is multiple sending less efficient than a single send?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69629408/

相关文章:

c# - 在 C# 中按名称获取和保存属性引用的最佳方法是什么

c - Linux UDP 套接字/端口重用

python - 我们什么时候在程序中添加错误处理代码?

c# - PowerBI 身份验证 C#

c# - 使用 MVVM 动态添加时给予 TabItem 焦点

c# - Wpf 应用程序卡住 - 大量内存泄漏之谜

c++ - 使用 Telnet 测试 select()

具有http多部分formdata POST方法的Java套接字

java - 如何将对象从一台计算机发送到另一台计算机?

c# - 如何限制对 WCF 中某些方法的访问?