C#UDP数据包丢失虽然所有数据包都到达(WireShark)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了C#UDP数据包丢失虽然所有数据包都到达(WireShark),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2922字,纯文字阅读大概需要5分钟。
内容图文
正如标题所说我在C#中遇到UDP问题.
我正在尝试为DayZ游戏的rcon协议构建一个库.
我的问题是我没有收到我应该收到的每一个数据包.
发送命令后,服务器回复分裂答案.包头包含总包数和当前包的索引.
现在,如果我应该获得17个数据包,我的应用程序中只能获得8-15个数据包.
在使用WireShark进行测试后,我现在知道所有包都到达了我的计算机.他们只是不被我的应用程序或类似的东西认可.
我的实际问题是:
是否可以防止丢失我的网卡和我的应用程序之间的包?要么
为什么会这样?
这是我目前的代码.它非常脏,因为我在没有按预期工作后撕开了它:
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) { }
}
}
}
}
解决方法:
这通常是因为您没有足够快地使用数据报,因此内核中的套接字缓冲区已满,网络堆栈开始丢弃新到达的数据包.一些要点:
>增加套接字上的接收缓冲区,
>不要在每次迭代时获取锁定 – 尽可能多地读取,然后将数据放入队列,
>考虑非阻塞方法而不是线程.
内容总结
以上是互联网集市为您收集整理的C#UDP数据包丢失虽然所有数据包都到达(WireShark)全部内容,希望文章能够帮你解决C#UDP数据包丢失虽然所有数据包都到达(WireShark)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。