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)我认为我正在做的答案是建议的,但问题仍然存在。
答案 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);
}
}