C# UdpClient - 监听器没有收到所有发送的数据包
C# UdpClient - Listener not receiving all packets sent
我想创建一个简单的 UdpClient 侦听器进程和一个 UdpClient 发布器进程作为更大规模项目的概念证明。我创建了一个简单的 UdpClient 侦听器,用于侦听在本地端口上发送的消息。此侦听器的代码如下。
// UdpMessageReceiver
class Program
{
static async Task Main(string[] args)
{
const int Port = 5001;
await UdpListener(Port);
}
public static async Task UdpListener(int port)
{
var client = new UdpClient(port, AddressFamily.InterNetwork);
var receivedCount = 0;
while (true)
{
var receivedResult = await client.ReceiveAsync();
var resultString = Encoding.ASCII.GetString(receivedResult.Buffer);
receivedCount++;
Console.WriteLine("Message: " + resultString);
Console.WriteLine("Current Message Total: " + receivedCount);
}
}
}
我还创建了一个消息发布器,它创建消息并将消息发送到我的侦听器正在侦听的同一本地端口,在本例中为端口 5001。消息发布器的代码如下。
class Runner
{
public static string Host = "127.0.0.1";
public static int Port = 5001;
// The Message class contains an id prop of type int and a packet prop of type byte[]
public static async Task<ConcurrentBag<Task>> BuildAndExecuteTasksAsync(ConcurrentBag<Message> messages)
{
var tasks = new ConcurrentBag<Task>();
Parallel.ForEach(messages, message =>
{
var sendTask = SendUdpMessageAsync(message);
tasks.Add(sendTask);
});
await Task.WhenAll(tasks);
return tasks;
}
public static async Task SendUdpMessageAsync(Message message)
{
var client = new UdpClient(Host, Port);
await client.SendAsync(message._packet, message._packet.Length);
}
}
此代码段是我生成要发送的消息列表的方式。
const int NUMBER_OF_MESSAGES = 5000;
var messages = new ConcurrentBag<Message>();
for (int i = 0; i < NUMBER_OF_MESSAGES; i++)
{
var messageToSend = "Hello World from Id: " + i;
var packetToSend = Encoding.ASCII.GetBytes(messageToSend);
messages.Add(new Message(i, packetToSend));
}
上面的代码确实有效。我启动侦听器,然后我 运行 发布者和侦听器接收并将所有消息打印到控制台。当我尝试一次发送大量数据包时,问题就来了。侦听器仅接收和处理前 2,700 个左右的数据包。未收到从发布者发送的所有其他数据包。我可以做些什么来确保所有数据包都被我的侦听器接收到,或者我是否需要更改消息在发布者中的发送方式?
UDP报文丢失是正常的。这不仅发生在 UDP 上,也发生在 TCP 上。 TCP丢包时的区别,它会通知发送方丢包,应该重发。
这就是 UDP 速度更快但准确性较低的原因。
如果您确实希望所有消息都能通过,请使用 TCP。
我想创建一个简单的 UdpClient 侦听器进程和一个 UdpClient 发布器进程作为更大规模项目的概念证明。我创建了一个简单的 UdpClient 侦听器,用于侦听在本地端口上发送的消息。此侦听器的代码如下。
// UdpMessageReceiver
class Program
{
static async Task Main(string[] args)
{
const int Port = 5001;
await UdpListener(Port);
}
public static async Task UdpListener(int port)
{
var client = new UdpClient(port, AddressFamily.InterNetwork);
var receivedCount = 0;
while (true)
{
var receivedResult = await client.ReceiveAsync();
var resultString = Encoding.ASCII.GetString(receivedResult.Buffer);
receivedCount++;
Console.WriteLine("Message: " + resultString);
Console.WriteLine("Current Message Total: " + receivedCount);
}
}
}
我还创建了一个消息发布器,它创建消息并将消息发送到我的侦听器正在侦听的同一本地端口,在本例中为端口 5001。消息发布器的代码如下。
class Runner
{
public static string Host = "127.0.0.1";
public static int Port = 5001;
// The Message class contains an id prop of type int and a packet prop of type byte[]
public static async Task<ConcurrentBag<Task>> BuildAndExecuteTasksAsync(ConcurrentBag<Message> messages)
{
var tasks = new ConcurrentBag<Task>();
Parallel.ForEach(messages, message =>
{
var sendTask = SendUdpMessageAsync(message);
tasks.Add(sendTask);
});
await Task.WhenAll(tasks);
return tasks;
}
public static async Task SendUdpMessageAsync(Message message)
{
var client = new UdpClient(Host, Port);
await client.SendAsync(message._packet, message._packet.Length);
}
}
此代码段是我生成要发送的消息列表的方式。
const int NUMBER_OF_MESSAGES = 5000;
var messages = new ConcurrentBag<Message>();
for (int i = 0; i < NUMBER_OF_MESSAGES; i++)
{
var messageToSend = "Hello World from Id: " + i;
var packetToSend = Encoding.ASCII.GetBytes(messageToSend);
messages.Add(new Message(i, packetToSend));
}
上面的代码确实有效。我启动侦听器,然后我 运行 发布者和侦听器接收并将所有消息打印到控制台。当我尝试一次发送大量数据包时,问题就来了。侦听器仅接收和处理前 2,700 个左右的数据包。未收到从发布者发送的所有其他数据包。我可以做些什么来确保所有数据包都被我的侦听器接收到,或者我是否需要更改消息在发布者中的发送方式?
UDP报文丢失是正常的。这不仅发生在 UDP 上,也发生在 TCP 上。 TCP丢包时的区别,它会通知发送方丢包,应该重发。
这就是 UDP 速度更快但准确性较低的原因。
如果您确实希望所有消息都能通过,请使用 TCP。