更新:现在是感觉udp发送的代码太碎了,就是说发送过来的数据就是几字节一帧就发过来了,导致接够能进行处理的整包数据需要接收很多次,然后导致整个系统的延迟。
一段同样的程序 在四台电脑上运行正常 在一台平板手持电脑上运行特别慢 四台电脑都比这个平板电脑配置低 平板电脑32G内存 I7 7500u 2.9GCPU有解惑的吗?
程序是用C#写,开了两个后台线程,一个线程udp同步接收数据并放入一个缓存,另一个线程处理数据。下面是代码
udpTeleReceiver = new UdpClient(int.Parse(PortTeleRece));
udpTeleSenderEndPoint = new IPEndPoint(IPAddress.Parse(stringIpInfo), int.Parse(PortTeleRece));
if (threadRecvTeleData == null)
{
threadRecvTeleData = new Thread(delegate() { RevTeleDataMethod(); });
threadRecvTeleData.Start();
threadRecvTeleData.IsBackground = true;
}
if (threadHandleRecvTeleData == null)
{
threadHandleRecvTeleData = new Thread(delegate() { RevTeleDataHandleMethod(); });
threadHandleRecvTeleData.Start();
threadHandleRecvTeleData.IsBackground = true;
}
private void RevTeleDataMethod()
{
while (true)
{
Thread.Sleep(1);
try
{
byte[] btTeleData = udpTeleReceiver.Receive(ref udpTeleSenderEndPoint);
if (btTeleData.Length >0)
{
if (btTeleData[6] == 0x15 && btTeleData[7] == 0x07)
{
}
else
{
Uav_Data.isNewData = true;
Uav_Data.tickCount = 0;
//添加加入list代码
lstRecBuffDataTemp.AddRange(btTeleData);
}
}
}
catch (Exception ex)
{
}
continue;
}
}
private void RevTeleDataHandleMethod()
{
while (true)
{
Thread.Sleep(1);
//大于134个字节开始处理
while (lstRecBuffDataTemp.Count >= 134)
{
try
{
int intdexFindA5 = lstRecBuffDataTemp.IndexOf(0xEB);
int indexFindA5Second = lstRecBuffDataTemp.IndexOf(0xEB, intdexFindA5+1);
int indexFindA5Third = lstRecBuffDataTemp.IndexOf(0xEB, indexFindA5Second + 1);
if (lstRecBuffDataTemp[intdexFindA5 + 1] == 0x90 )
{
int lengthRecBuffData = lstRecBuffDataTemp[intdexFindA5 + 2 + 6] + 6;
Uav_Data.strUavInfo.FlyNum = lstRecBuffDataTemp.Count;
byte[] bttempRecTeledata = new byte[lengthRecBuffData];
lstRecBuffDataTemp.CopyTo(intdexFindA5, bttempRecTeledata, 0, lengthRecBuffData);
byte[] btreceivedWrite = new byte[lengthRecBuffData + 9];
btreceivedWrite[0] = (byte)(lengthRecBuffData + 9);
Buffer.BlockCopy(BitConverter.GetBytes(DateTime.Now.Ticks), 0, btreceivedWrite, 1, 8);//添加时间戳进行文件记录
Buffer.BlockCopy(bttempRecTeledata, 0, btreceivedWrite, 9, lengthRecBuffData);
GCSFileTool.FileWriter.StreamWriteFunc(btreceivedWrite);
ResolutionSourceData(bttempRecTeledata, lengthRecBuffData);
if (NetDisPlayForm.isDisPlayRemoteData)
{
EventRemoteData(bttempRecTeledata);
}
lstRecBuffDataTemp.RemoveRange(0, intdexFindA5 + lengthRecBuffData);
}
else
{
lstRecBuffDataTemp.RemoveRange(0, intdexFindA5 + 1);
continue;
}
}
catch (Exception)
{
lstRecBuffDataTemp.RemoveRange(0, 134);
}
}
}
}
UdpClient client = new UdpClient(3381);
Task.Run(async () =>
{
while (true)
{
//请直接使用异步,不要使用某园子的“高级sleep”
//这个就是你接收的结果
var udppackge = await client.ReceiveAsync();
//buffer就是数据包
var buffer = udppackge.Buffer;
//这个是远程ip
var rip = udppackge.RemoteEndPoint;
//udp不存在粘包无需在跟某园子学啥list分析了,下面请直接使用
//我这里用span传递,只是不想重新分配内存
//如果框架版本低,直接用 byte[]也行
ProcessMsg(buffer.AsSpan());
}
});
Task ProcessMsg(Span<byte> data)
{
//把data重新在栈内分配一个变量,避免闭包穿越
var _data=data;
return Task.Run(() =>
{
//这里分析数据是否你想要的
// if(_data is xxxxx)
//如果是你想要的,你用事件传递还是用消息队列传递
//就随便你了
});
}
看看是不是网络的问题。
不知道你这个问题是否已经解决, 如果还没有解决的话:首先,需要确认问题是出在UDP接收数据过慢上还是数据处理速度上。可以通过测试不使用后台线程,只在主线程中接收数据,看看是否有更快的速度。
如果问题出在UDP接收数据速度上,可以尝试以下几步优化:
UdpClient udpClient = new UdpClient(port);
udpClient.Client.ReceiveBufferSize = 1024 * 1024; // 设置缓存大小为1MB
var tasks = new List<Task>();
for (int i=0; i<numberOfThreads; i++)
{
var task = Task.Run(() => ReceiveData(udpClient));
tasks.Add(task);
}
await Task.WhenAll(tasks);
private async Task ReceiveData(UdpClient udpClient)
{
while (true)
{
var result = await udpClient.ReceiveAsync();
var buffer = result.Buffer;
// 处理数据
}
}
如果问题出在数据处理速度上,可以尝试以下几步优化:
ThreadPool.QueueUserWorkItem(ProcessData, data);
总之,需要先确定问题在哪里,然后针对性地进行优化。同时,在进行优化时,需要兼顾效率和稳定性,避免因优化而引入新的问题。