c# - 如何增加 UDPClient 吞吐量

标签 c# linux network-programming .net-core datagram

我正在研究 .NET Core 在 Linux 机器上的性能。具体来说,确定框架本身可用的工具可能存在什么样的限制。

我一直以 ~ 50,000 pps 的价格击中盒子。到目前为止,似乎 ~ 20,000 pps 是 UDPClient 在相当多的数据包被丢弃之前能够实现的。使用另一种工具 (syslog-ng),丢包率很少/很低。

如果我希望处理超过 50K pps,UdpClient 是否能够通过适当的调整来处理这个问题?

using (UdpClient udpListener = new UdpClient(_sysLogPort))
{
    udpListener.Client.ReceiveBufferSize = _bufferSize;

    while (!_cts.IsCancellationRequested)
    {
        try
        {
            UdpReceiveResult result = await udpListener.ReceiveAsync();
        }
        catch (Exception ex)
        {

        }
    }
}

最佳答案

即使您的应用使用 udpListener.ReceiveAsync(); 启动新线程,它也会在尝试接收新数据包之前等待其终止。所以一次只有一个线程处理一个新接收到的UDP数据包来创建一个UdpReceiveResult类型的对象。因此,它非常类似于单线程应用:您利用在多核系统上运行的机会。

您可能会获得更好的价格(显然取决于您的硬件),使用以下方式编写您的程序。在此示例中,有一个包含 5 个线程的池,这些线程并行运行以同时创建 UdpReceiveResult 的多个实例。即使内核一次处理一个数据包,创建 UdpReceiveResult 实例的用户空间进程也是并行完成的,采用这种编程方式。

// example of multithreaded UdpClient with .NET core on Linux
// works on Linux OpenSuSE LEAP 42.1 with .NET Command Line Tools (1.0.4)
// passed tests with "time nping --udp -p 5555 --rate 2000000 -c 52000 -H localhost > /dev/null"

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows;

namespace hwapp {
  class Program {
    // listen to port 5555
    UdpClient udpListener = new UdpClient(5555);

    static void Main(string[] args) {
      Program p = new Program();
      // launch 5 threads
      Task t0 = p.listen("thread 0");
      Task t1 = p.listen("thread 1");
      Task t2 = p.listen("thread 2");
      Task t3 = p.listen("thread 3");
      Task t4 = p.listen("thread 4");
      t0.Wait(); t1.Wait(); t2.Wait(); t3.Wait(); t4.Wait();
    }

    public async Task listen(String s) {
      Console.WriteLine("running " + s);
      using (udpListener) {
        udpListener.Client.ReceiveBufferSize = 2000;
        int n = 0;
        while (n < 10000) {
          n = n + 1;
          try {
            UdpReceiveResult result = udpListener.Receive();
          } catch (Exception ex) {}
        }
      }
    }
  }
}

关于c# - 如何增加 UDPClient 吞吐量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45578855/

相关文章:

c# - 将编译日期添加到代码中

c# - 尝试使用 LDAP 连接来连接 AD 时出错

c# - 从 JSON 发布反序列化 int 数组

c++ - RST 数据包是否会被发送到应用程序而不考虑其序列号?

c# - 在运行时更改代码

c - 如何在Linux内核中使用vfs_readdir?

java - Raspberry Pi 上的 Jave 段错误

c++ - 如何调用存储在char数组中的机器码?

linux - 发送 (2) 在无法访问的网络上成功建立连接

python - 如何在 python 中正确执行 host 或 dig 命令