c# - UDP 接收器是否能够一次处理数千个接收到的数据包?C#
问题描述
当许多 UDP 消息同时出现时,我担心会收到不完整的 UDP 包。
微软是否在操作系统中包含某种控制器来捕获 UDP,然后如果有程序正在监听,则将它们连续传递到指定的端口(消息到达的端口)?
我创建了这种代码。这是否有助于捕获 5000 条消息?ProcessReceivedBytes方法应该异步运行,并且在处理字节时它应该已经再次监听,我正确吗?
while (_run) { byte[] bytes = _client.Receive(ref _endPoint); ProcessReceivedBytes(bytes); }
下面这个类的完整代码。实现是在程序中创建实例然后开始监听。
public delegate void LoggingMethod(string log);
public delegate void LoggingMethodError(Exception e);
public delegate void ProcessReceivedBytes(byte[] receivedBytes);
public class UDPListener
{
private bool _isListening;
private bool _isClosed;
private bool _run;
private int _port;
private IPAddress _ipAdress;
private IPEndPoint _endPoint;
private UdpClient _client;
private LoggingMethod _logNormal;
private LoggingMethodError _logError;
private ProcessReceivedBytes _processReceived;
Task _processBytes;
public int Port { get => _port;}
public string IpAdress { get => _ipAdress.ToString(); }
public UDPListener(int port, string ipAdress, ProcessReceivedBytes processReceived)
{
_port = port;
_ipAdress = IPAddress.Parse(ipAdress);
_processReceived = processReceived;
}
public UDPListener(int port, string ipAdress, ProcessReceivedBytes processReceived, LoggingMethod logNormalState, LoggingMethodError logErrorState) : this(port, ipAdress, processReceived)
{
_logNormal = logNormalState;
_logError = logErrorState;
}
public async Task StartListening()
{
LogNormalState("Setting up client and endpoint.");
_run = true;
_client = new UdpClient(_port);
_isClosed = false;
_endPoint = new IPEndPoint(_ipAdress, _port);
LogNormalState("Starting to listen.");
try
{
_isListening = true;
while (_run)
{
byte[] bytes = _client.Receive(ref _endPoint);
ProcessReceivedBytes(bytes);
}
}
catch (SocketException e)
{
if (e.ErrorCode == 10004)
{
LogNormalState("A socket exception (10004) was thrown. It's okay if the listener was closed by method StopListening.");
}
else
{
await LogErrorState(e);
}
}
catch (Exception e)
{
await LogErrorState(e);
}
finally
{
CloseClient();
}
}
public bool IsListening()
{
return _isListening;
}
public bool IsClosed()
{
return _isClosed;
}
public void StopListening()
{
int waiterLimit = 100;
int waiterCounter = 0;
LogNormalState("Listening stopped by method StopListening.");
_run = false;
LogNormalState("Waiting 100ms before socket hard closure.");
while (waiterCounter <= waiterLimit)
{
Thread.Sleep(1);
waiterCounter++;
}
CloseClient();
}
private void CloseClient()
{
if (!IsClosed())
{
_isListening = false;
LogNormalState("Listening stopped.");
LogNormalState("Closing client.");
_client.Close();
_isClosed = true;
}
}
private void LogNormalState(string log)
{
if (_logNormal != null)
{
_logNormal.Invoke(log);
}
}
private async Task LogErrorState(Exception e)
{
if (_logError != null)
{
_logError.Invoke(e);
}
}
private async Task ProcessReceivedBytes(byte[] bytes)
{
if (_processReceived != null)
{
_processReceived.Invoke(bytes);
}
}
}
}
解决方案
推荐阅读
- powerbi - RANKX 函数在它排名的所有值中给出重复项
- javascript - 从数组中返回正确的项目
- django - 在单个模板中处理多个表单在 django 中不起作用
- amazon-web-services - 在 terraform 中动态创建资源
- javascript - 如何根据父 div 的高度调整 ReactJS 组件的高度?
- nsis - 按变量选择部分
- python - 正则表达式仅匹配第二个条目
- node.js - 如何将上传的文件从前端上传到服务器,然后再上传到另一台服务器
- nginx - Nginx 使用 `#` 符号转发到不同应用程序的不同路径
- javascript - 在 vue i18n 中分别使用数字和消息本地化