【问题标题】:Can I use blocking TCP Socket.Send in a server loop?我可以在服务器循环中使用阻塞 TCP Socket.Send 吗?
【发布时间】:2014-02-10 18:54:37
【问题描述】:

如果其中一个套接字阻塞了 Send(),它可能会影响其他客户端。我很担心: Send() 是否等待“已交付”的答案?如果它比远程客户端可以通过忽略传入的数据包来阻止我的服务器事件处理循环 - 那么我应该使用 BeginSend。但是我测量到 BeginSend 会消耗更多的 CPU。所以我想知道在服务器事件循环中使用阻塞发送是否可以接受?

如 MSDN 所述

成功完成发送并不表示数据已成功传递。

我知道当它的发送缓冲区被填满时,socket 也会阻塞。

【问题讨论】:

  • But I've measured that BeginSend eats more CPU我想看看你是怎么测量的。
  • 我在网络引擎负载测试中将 Send 替换为 BeginSend 以检查它。 2000 个客户端每 200 毫秒发送和接收一个数据包,而服务器同时向它们发送随机数据包(以模拟 n^n 小型相关集负载)。 Send 显示 14-15% 的服务器 CPU 负载,BeginSend 显示 17-18%。抱歉,我无法将我的网络代码发送给您,因为它非常庞大且复杂:)
  • @L.B 您可能认为 3-4% 的开销并不合理,但服务器是性能关键的应用程序,我希望尽可能快。
  • 我也不认为你的测试是正确的。请参阅我的第一条评论。我试图以礼貌的方式暗示它。
  • 你似乎下定决心要使用你的方法,然后使用它,但不要指望我们说你在正确的轨道上

标签: c# sockets networking tcp


【解决方案1】:

如果其中一个套接字阻止了 Send(),它可能会影响其他客户端。

仅当您的服务器是单线程时。解决方案:多线程。

我很担心:Send() 会等待“已交付”的答案吗?

不,但如果客户端没有读取并且缓冲区已满,它可能会阻塞。

如果远程客户端可以通过忽略传入的数据包来阻止我的服务器事件处理循环 - 那么我应该使用 BeginSend。但是我测量到 BeginSend 会消耗更多的 CPU。所以我想知道在服务器事件循环中使用阻塞发送是否可以接受?

不,不是。如果可以克服厌恶,请使用多线程、非阻塞 I/O 或异步 I/O。您关于 3-4% 开销的建议对我来说听起来不正确。

【讨论】:

  • “如果客户端不阅读,它可以阻止” - 你能提供更多信息吗?
  • 我已经使用异步 IO 来接收。什么“厌恶”?我使用多线程,但我会查看它的执行速度,并在单线程更适合或其他优化的地方进行改进。如果你不像这样优化你的网络核心,你甚至不会达到实时网络游戏的 200 个客户端限制。每个百分比都很重要。
  • @Vlad 我从您的问题和 cmets 中了解到,您没有提出任何要求,但希望您的方法得到批准。抱歉,我不这么认为。
  • “不,但如果客户端没有读取并且缓冲区已满,它可能会阻塞。”我能以某种方式确定缓冲区填充了多少吗?
  • @Vlad If you can refute my approach I'll consider that 不,我不会试图反驳。这是你的问题/问题不是我的。顺便说一句:使用您的问题或此答案发表评论。很难跟随你的 cmets。
猜你喜欢
  • 2012-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-04
  • 2012-01-19
  • 2017-11-08
相关资源
最近更新 更多