C# UDP packetloss though all packets arrive (WireShark)(尽管所有数据包都到达,但 C# UDP 数据包丢失 (WireShark))
问题描述
正如标题所说,我在 C# 中遇到了 UDP 问题.我正在尝试为 DayZ 游戏的 rcon 协议构建一个库.
As the title says I have a problem with UDP in C#. I'm trying to build a library for the rcon protocol of the game DayZ.
我的问题是我没有收到我应该收到的每个数据包.发送命令后,服务器回复一个拆分答案.数据包头包含总数据包计数和当前数据包的索引.现在,如果我应该得到 17 个数据包,我的应用程序中只会得到 8-15 个数据包.
My problem is that I dont receive every packet I should receive. After sending a command the server replies with an split answer. The packet header contains the total packet count and the index of the current packet. Now if I should get 17 packets I only get 8-15 packets in my application.
在使用 WireShark 进行测试后,我现在知道所有包裹都到达了我的计算机上.他们只是没有得到我的应用程序或类似的东西的认可.
After testing with WireShark I know now that all packages arrive on my computer. They just dont get recognized by my application or something like that.
我的实际问题是:是否可以防止丢失我的网卡和我的应用程序之间的包?或者为什么会这样?
My Actual Question is: Is it possible to prevent losing the packages between my network card and my application? or Why does that happen?
这是我当前的代码.它很脏,因为我在没有按预期工作后把它撕开了:
Here is my current code. Its pretty dirty because I ripped it apart after not working as expected:
    private Socket _udpClient;
    private Thread _receiverThread;
    private Thread _workerThread;
    private Queue<byte[]> _packetQueue;
    private PacketBuffer[] MessageBuffer;
    private byte SenderSequence = 0;
    private IPEndPoint connection;
    public RCon(IPAddress ip, int port)
    {
        connection = new IPEndPoint(ip, port);
        _udpClient = new Socket(connection.Address.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
        _udpClient.Connect(connection);
        MessageBuffer = new PacketBuffer[256];
        _packetQueue = new Queue<byte[]>();
        _receiverThread = new Thread(new ThreadStart(ReceiveCallback));
        _receiverThread.IsBackground = true;
        _receiverThread.Priority = ThreadPriority.AboveNormal;
        _receiverThread.Start();
        _workerThread = new Thread(new ThreadStart(WorkerCallback));
        _workerThread.IsBackground = true;
        _workerThread.Start();
    }
    public void Login(string password)
    {
        LoginPacket packet = new LoginPacket(password);
        _udpClient.Send(packet.Bytes);
    }
    public void SendCommand(string command)
    {
        CommandPacket packet = new CommandPacket(SenderSequence, command);
        SenderSequence++;
        _udpClient.Send(packet.Bytes);
    }
    private void ReceiveCallback()
    {
        while (true)
        {
                byte[] buffer = new byte[1036];
                if (_udpClient.Receive(buffer) > 0)
                    _packetQueue.Enqueue(buffer);
        }
    }
    private void WorkerCallback()
    {
        while (true)
        {
            if (_packetQueue.Count > 0)
            {
                byte[] buffer = _packetQueue.Dequeue();
                if (buffer != null)
                {
                    try
                    {
                        Packet receivedPacket = Packet.ParseIncoming(buffer);
                        OnPacketReceived(new PacketReceivedEventArgs(receivedPacket));
                        switch (receivedPacket.Type)
                        {
                            case PacketType.Message:
                                OnMessageReceived(new MessageReceivedEventArgs(receivedPacket.Content));
                                MessageCallbackPacket packet = new MessageCallbackPacket(receivedPacket.SequenceNumber);
                                _udpClient.Send(packet.Bytes);
                                break;
                            case PacketType.CommandCallback:
                                if (MessageBuffer[receivedPacket.SequenceNumber] == null)
                                    MessageBuffer[receivedPacket.SequenceNumber] = new PacketBuffer(receivedPacket);
                                else
                                    MessageBuffer[receivedPacket.SequenceNumber].AddPacket(receivedPacket);
                                if (MessageBuffer[receivedPacket.SequenceNumber].IsComplete)
                                    OnCommandCallback(new CommandCallbackEventArgs(MessageBuffer[receivedPacket.SequenceNumber].GetContent()));
                                break;
                        }
                    }
                    catch (ArgumentException) { }
                    catch (OverflowException) { }
                    catch (FormatException) { }
                }
            }
        }
    }
推荐答案
这通常是因为你没有足够快地使用你的数据报,所以内核套接字缓冲区已满,网络堆栈开始丢弃新到达的数据包.几点:
This is usually because you are not consuming your datagrams fast enough, so in-kernel socket buffer gets full and the network stack starts dropping newly arriving packets. Some points:
- 增加套接字上的接收缓冲区,
- 不要在每次迭代时都获取锁 - 尽可能多地读取,然后将数据放入队列中,
- 考虑非阻塞方法而不是线程.
这篇关于尽管所有数据包都到达,但 C# UDP 数据包丢失 (WireShark)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:尽管所有数据包都到达,但 C# UDP 数据包丢失 (WireShark)
 
				
         
 
            
        基础教程推荐
- 在 VS2010 中的 Post Build 事件中将 bin 文件复制到物 2022-01-01
- 首先创建代码,多对多,关联表中的附加字段 2022-01-01
- 是否可以在 asp classic 和 asp.net 之间共享会话状态 2022-01-01
- 经典 Asp 中的 ResolveUrl/Url.Content 等效项 2022-01-01
- 如何动态获取文本框中datagridview列的总和 2022-01-01
- 错误“此流不支持搜索操作"在 C# 中 2022-01-01
- JSON.NET 中基于属性的类型解析 2022-01-01
- 全局 ASAX - 获取服务器名称 2022-01-01
- 将事件 TextChanged 分配给表单中的所有文本框 2022-01-01
- 从 VS 2017 .NET Core 项目的发布目录中排除文件 2022-01-01
 
    	 
    	 
    	 
    	 
    	 
    	 
    	 
    	 
						 
						 
						 
						 
						 
				 
				 
				 
				