【问题标题】:thread too slow on sockets套接字上的线程太慢
【发布时间】:2020-02-18 13:14:06
【问题描述】:

我正在使用 Visual Studio Express 2013 为移动机器开发一个服务器,该服务器实现了一个套接字服务器来接收它们的连接。

它使用Net.Sockets.TcpListener.AcceptSocket 将连接分配给Net.Sockets.Socket。 它为每个创建的新套接字启动一个新的Threading.Thread,并在一段时间内接收、解析和写入数据到套接字。 它使用属性x.Available 获取数据计数并使用x.Receive(buffer, datalen, Net.Sockets.SocketFlags.None) 读取该数据。 它解析接收到的数据并创建答案。 最后它使用x.Send(answerbuffer, answerdatalen, Net.Sockets.SocketFlags.None) 来传递答案。

代码在接收和发送答案时可以正常工作,但速度很慢。

我对代码进行了一些检查,以获取代码每次操作的经过时间,并得到平均值: - 套接字从缓冲区读取数据并将数据复制到列表(字节):100-200 ms - 数据解析和创建应答缓冲区列表(字节):150-300 ms - 将缓冲区列表(字节)转换为缓冲区字节数组和套接字发送:70-200 毫秒

请记住,数据包的数据接收长度约为 150 字节,数据传输长度约为 100 字节,线程的每个执行部分的时间都非常高。因此,当服务器同时接收到更多连接时,响应速度会变慢或停止一段时间。

这种为服务器上的每个连接使用 Socket 和 Thread 的方法是否不好? 我是否要搜索其他类来管理数据流或线程并行执行? Visual Studio Express 在使用线程方面是否有一些限制?

感谢您的帮助。 马特奥

【问题讨论】:

  • 如果这些是临时连接,使用 AcceptSocketAsync 可能会快得多,因为这将使用线程池。

标签: .net multithreading sockets visual-studio-2013


【解决方案1】:

这种为服务器上的每个连接使用一个Socket和一个线程的方法是不是很糟糕?

是的,非常糟糕。线程根本无法扩展,此外:如果您在每个套接字上使用线程,则几乎可以保证意外或恶意 DDOS。

如果您只连接到几个套接字,您可以几乎在客户端使用每个套接字线程。在服务器上:这就是死亡。

服务器套接字 IO 几乎总是使用异步 IO 完成。这会变得很复杂真的很快,尤其是在谈论后台缓冲区等时,但是:现代 .NET 中有一个全新的 API 可用于这种情况:“管道” - 处理所有线程、内存池和后台缓冲区管理为您服务。不过,它真的 不会在 Visual Studio 2013 上运行,所以……如果可能的话,更新一下?如果有兴趣,我有一个multi-part saga on using pipelines

如果这不可能,一个好的起点可能是 SocketAsyncEventArgs,但再说一遍:这是一个非常深的兔子洞,坦率地说,这基本上是一个已解决的问题.如果您可以切换到预先推出的实现,我会推荐它。

【讨论】:

  • 感谢您的帮助。我将 Visual Studio 更新到 2019 年,并研究了您关于管道的传奇。我认为准备好使用管道进行内存管理,但是在决定线程管理方面有很多困难。我最多有 50 台机器可以同时连接,每台机器都可以保持连接并随机传输数小时的数据更新。服务器每 5 分钟请求一次机器心跳(连接仍然存在?),并在连接之间路由数据。您是否也对此特定用途的“异步 IO”管理有一些提示?
  • @matteo 与管道?实际上无事可做;你会被自动激活
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-19
  • 1970-01-01
  • 2019-09-26
  • 2018-02-28
  • 2013-05-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多