C#udp服务器读取速度不够快

时间:2017-02-20 09:58:26

标签: c# sockets udp

public class RCon
{
    static readonly ConcurrentQueue<byte[]> ReceivedPacketQueue = new ConcurrentQueue<byte[]>();
    static IPEndPoint _ipEndPoint = new IPEndPoint(IPAddress.Parse("10.XXX.XX.117"), 2222); 

    static void Main(string[] args)
    {
        var client = new UdpClient
                         {
                             ExclusiveAddressUse = false,
                             Client = { ReceiveBufferSize = 8192 }
                          };

        client.Client.Bind(_ipEndPoint);
        client.BeginReceive(OnUdpData, client);

        var message = new byte[100];
        int numberOfPackets ;

        for (numberOfPackets = 0; numberOfPackets < 84; numberOfPackets++)
        {
             client.Send(message, message.Length, _ipEndPoint);
        }
    }

    static void OnUdpData(IAsyncResult result)
    {
        var socket = result.AsyncState as UdpClient;
        var message = socket.EndReceive(result, ref _ipEndPoint);
        ReceivedPacketQueue.Enqueue(message);
        socket.BeginReceive(OnUdpData, socket);
    }
}

我编写了一个简单的程序,它发送100个字节的数据包,与服务器相同的机器异步接收数据包并存储在队列中。收到的数据包很好,直到数据包数为83一旦我开始增加超过84个数据包的数量,收到的数据包速率就会下降。据我所知,这是因为客户端读取传入的数据包速度不够快,而且当缓冲区溢出时数据包丢失。有什么方法可以使服务器足够快,以接收快速传入的数据包。

有类似的问题C# UDP packetloss though all packets arrive (WireShark)我认为我正在做的答案是建议的,但问题仍然存在。

1 个答案:

答案 0 :(得分:0)

好吧,它在服务器和客户端的同一端口使用相同的ip :)

我用您的代码进行了测试。我添加了2个静态变量 static int sendIter = 0; static int recvIter = 0;

并运行该应用。它以sendIter = 84和recvIter = 0..2-3迭代退出

我认为这是因为您在函数中开始异步操作(BeginReceive),然后立即启动循环以发送消息。 在引擎盖下BeginReceive启动线程,但它没有机会将上下文切换到自身,即使它已准备好处理传入消息因为这个for循环 - 它需要所有的cpu时间。

然后我在client.Send之后添加了Thread.Sleep(1)(它将允许应用程序切换线程上下文)并且我得到了sendIter和recvIter相等

所以我认为如果有cpu时间,客户端足够快

class Program
{
    static readonly ConcurrentQueue<byte[]> ReceivedPacketQueue = new ConcurrentQueue<byte[]>();
    static IPEndPoint _ipEndPoint = new IPEndPoint(IPAddress.Parse("192.168.4.142"), 2222);
    static int sendIter = 0;
    static int recvIter = 0;

    static void Main(string[] args)
    {
        var client = new UdpClient
        {
            ExclusiveAddressUse = false,
            Client = { ReceiveBufferSize = 8192 }
        };

        client.Client.Bind(_ipEndPoint);
        client.BeginReceive(OnUdpData, client);

        var message = new byte[100];
        int numberOfPackets;

        for (numberOfPackets = 0; numberOfPackets < 100; numberOfPackets++)
        {
            client.Send(message, message.Length, _ipEndPoint);
            Thread.Sleep(1);
            sendIter++;
        }

        Console.WriteLine(sendIter);
        Console.WriteLine(recvIter);
        Console.ReadKey();
    }

    static void OnUdpData(IAsyncResult result)
    {
        var socket = result.AsyncState as UdpClient;
        var message = socket.EndReceive(result, ref _ipEndPoint);
        ReceivedPacketQueue.Enqueue(message);
        recvIter++;
        socket.BeginReceive(OnUdpData, socket);
    }
}