【问题标题】:Total upload speed is slower when all connections are accepted by one TcpListener一个 TcpListener 接受所有连接时,总上传速度较慢
【发布时间】:2012-05-03 09:42:51
【问题描述】:

我最近在C# .NET Framework 4.0中遇到了一个奇怪的情况:


在一个简单的程序中,我创建了一个 TcpListener,指定它的本地端口,启动它并使用异步接受函数来接收传入的连接请求。

一旦它有待处理的入站连接,服务器就会从异步回调函数中接受 TcpClient 并将其记录到容器中(更具体地讲,List<TcpClient>)。

我编写了另一个简单的客户端程序,它一旦启动就连接到服务器,然后调用异步接收函数。

所有客户端连接后,服务器使用System.Threading.Tasks.Parallel.ForEach()启动一组并行任务。

在每个任务中,我使用存储在该列表中的 TcpClient 将数据发送到相应的客户端。所有 TcpClients 都在同时发送数据(我检查了客户端,它们都在接收数据)。数据只是一个byte[8192],在服务器程序启动时生成随机数据。我让服务器反复发送。

客户端的接收回调很简单。一旦数据到达,客户端只是忽略数据并运行另一个异步接收函数。

测试环境是一个1Gbps LAN一个服务器几个客户端

结果是:无论有多少客户端(3~8)连接到服务器,服务器的总上传速度永远不会超过13MByte/s。


然后我尝试了另一种方法:

我也在客户端创建了一个TcpListener。一旦客户端连接到服务器,服务器也会连接到客户端的监听端口。然后服务器会将这个传出连接存储到列表中,而不是传入连接。

这一次,测试结果变化很大:当3个客户端从服务器接收数据时,服务器的总上传速度接近30MByte/s; 5个客户端,总上传速度接近50MBytes/s

虽然这个10MByte/s-per-client 的限制可能是由于硬件或网络配置的原因,但它仍然比上面的情况要好得多。


有人知道为什么吗?

【问题讨论】:

    标签: c# performance sockets tcplistener


    【解决方案1】:

    我不知道这种行为的原因,但作为一种解决方法,我建议发送更大的缓冲区。像 1MB(或至少 64k)。在 1Gbps LAN 上,如果您的应用程序发送更大的块(和更少的数据包),您可能会更有效率。另外,启用巨型帧。

    【讨论】:

    • 我刚刚尝试了更大的套接字发送/接收缓冲区大小和更大的数据块。可惜没有欢乐。以及如何启用巨型帧?
    • 谷歌:启用巨型帧 ;-)
    • 感谢您的指导。但是我无法在我的网络环境中启用巨型帧,网络适配器不支持此功能,交换机也不支持。
    【解决方案2】:

    不要使用线程或任务进行处理。这会影响你的表现。

    我制作了一个框架,可以帮助您开发高性能的网络应用程序,而无需关心实际的 IO 处理。

    http://blog.gauffin.org/2012/05/griffin-networking-a-somewhat-performant-networking-library-for-net/

    【讨论】:

      猜你喜欢
      • 2012-01-16
      • 1970-01-01
      • 1970-01-01
      • 2012-11-11
      • 1970-01-01
      • 1970-01-01
      • 2016-03-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多