所以我有一堆我想要监听的不同端口,并且迭代可用数据以发送到Dataflow管道。我总共听了14个端口。 寻找有关如何减少以下代码的CPU使用率的任何建议。
所以我只是将端口传递给方法然后将它们添加到列表中
public static void AddPorts(Dictionary<int,string> ports)
{
try
{
var NewEndPoints = new List<IPEndPoint>();
foreach (var port in ports)
{
var endpoint = new IPEndPoint(IPAddress.Any, port.Key);
NewEndPoints.Add(endpoint);
if (!Endpoints.Contains(endpoint))
{
Endpoints.Add(endpoint);
var client = new UdpClient(endpoint);
logger.Info("New Client added on port: {0}", endpoint.Port);
Clients.Add(client);
}
else
{
if (IgnoredPorts.Contains(endpoint.Port))
{
logger.Info("Existing client enabled on port: {0}", endpoint.Port);
IgnoredPorts.Remove(port.Key);
}
}
}
var differences = Endpoints.Except(NewEndPoints);
differences.ToList().ForEach(d =>
{
if (!IgnoredPorts.Contains(d.Port))
{
IgnoredPorts.Add(d.Port);
logger.Info("Client removed on port: {0}", d.Port);
}
});
}
catch (Exception ex)
{
logger.Error("Error creating udpclients", ex);
}
}
然后我迭代任何可用的数据
Task.Run(async delegate
{
while (Receive)
{
try
{
// get any channels that have data availble
// Iterate over the the channels and send to Dataflow pipeline
var readyChannels =
(from channel in Clients
where channel.Available > 0 && !ListenersDF.IgnoredPorts.Contains(((IPEndPoint)channel.Client.LocalEndPoint).Port)
select channel);
// Iterate over the the channels and send to Dataflow pipeline
foreach (var channel in readyChannels)
{
// await on the result of the task
await ReceiveAndRespond(channel);
}
}
catch (Exception ex)
{
logger.Error("Error sending packet to bufferBlock", ex);
}
}
});
最后将其发送到数据流管道
async Task ReceiveAndRespond(UdpClient channel)
{
UdpReceiveResult? result = null;
try
{
result = await channel.ReceiveAsync();
}
catch (Exception exc)
{
logger.Error("Error receiving from channel: " + exc.Message, exc);
}
if (result != null)
{
var device = (from d in Ports
where d.Key == ((IPEndPoint)channel.Client.LocalEndPoint).Port
select d.Value).FirstOrDefault();
UdpData data = new UdpData() { Client = channel, Data = result.Value.Buffer, LocalPort = ((IPEndPoint)channel.Client.LocalEndPoint).Port, LocalIP = ((IPEndPoint)channel.Client.LocalEndPoint).Address, RemoteEndpoint = result.Value.RemoteEndPoint, Device = device };
Flow.bufferBlock.Post(data);
// for testing logs the hex string to a log file
//logger.Warn(string.Format("Data received on port: {0} for device: {1} with data: {2}", data.LocalPort, data.Device, data.Data.ByteArrayToHexString()));
}
}
然后cpu坐在50%,几乎没有流量,我确定有些事情搞砸了我是怎么做到这一点的。非常感谢任何帮助!
答案 0 :(得分:1)
我想,你应该改变你的设计。这是一个示例服务器代码。
public class UDPServer
{
public UDPServer(IEnumerable<int> listenPorts)
{
foreach(var port in listenPorts)
{
var udpClient = new System.Net.Sockets.UdpClient();
udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, port));
udpClient.BeginReceive(Receive, udpClient);
}
}
public void Receive(IAsyncResult ar)
{
var udpClient = ar.AsyncState as UdpClient;
IPEndPoint endPoint = null;
var data = udpClient.EndReceive(ar, ref endPoint);
//Do some work and send a response back
var dataToSend = Encoding.UTF8.GetBytes(String.Concat(Encoding.UTF8.GetString(data).Reverse()));
udpClient.Client.SendTo(dataToSend, endPoint);
udpClient.BeginReceive(Receive, udpClient);
}
}
现在,您可以像这样测试:
var server = new UDPServer(new[] { 10000, 10001, 10002 });
await Task.Delay(2000); //Just to keep the code simple, for now.
var udpClient = new UdpClient();
udpClient.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 10001));
while (true)
{
var line = Console.ReadLine();
if (line == ".") break;
var data = Encoding.UTF8.GetBytes(line);
udpClient.Send(data, data.Length);
IPEndPoint endPoint = null;
var recvData = udpClient.Receive(ref endPoint);
Console.WriteLine(Encoding.UTF8.GetString(recvData));
}