我正在创建一个基于套接字的遥测应用程序,我使用两个无线调制解调器发送/接收数据,一个应用程序通过调制解调器1发送数据,另一个程序通过调制解调器2获取数据,我的发送间隔是一秒,它似乎接收器应用程序(服务器)正在使用大部分CPU和RAM资源(99%的CPU使用率!),其内存使用量稳步增长!所以几分钟后我的程序几乎停止响应并且我的数据根本不正确,所以数据无法解析,似乎我的程序收到了几个已发送数据的副本,我的原始数据包大约是70个字节,但是经过一些它的大小增加秒,我认为我的接收缓冲区已满,数据与之前的数据混合,我正在寻找一些建议,这是我在服务器程序中的接收处理程序:
private void DataReceive()
{
handler.ReceiveBufferSize = 100;
try
{
byte[] bytes = new byte[100];
int byteRec;
while (true)
{
timer1.Enabled = true;
while (true)
{
byteRec = handler.Receive(bytes);
if (byteRec > 0)
{
data = System.Text.Encoding.UTF8.GetString(bytes, 0, byteRec);
break;
}
}
if (data.Length >= 30)
{
if (data.Substring(0, 1) == "#")//pasrse data, correct!
{
label27.Text = data.Length.ToString();
textBox1.Text = data;
string a = data.Substring(1);
string[] b = a.Split('-');
SetControlPropertyThreadSafe(lblTotal, "Text", b[0]);
SetControlPropertyThreadSafe(lblFlow, "Text", b[1]);
float real_analog2 = (1 - (((20 - float.Parse(b[4])) / (20 - 4)))) * Analog2_Max;
if (real_analog2 < 0)
real_analog2 = 0;
SetControlPropertyThreadSafe(lblAnalog, "Text", real_analog2.ToString());
if (b[2] == "1")//off
SetControlPropertyThreadSafe(lblMotion, "Text", "off");
else if (b[2] == "0")//on
SetControlPropertyThreadSafe(lblMotion, "Text", "on");
if (b[3] == "1")//off
SetControlPropertyThreadSafe(lblMotion2, "Text", "off");
else if (b[3] == "0")//on
SetControlPropertyThreadSafe(lblMotion2, "Text", "on");
SetControlPropertyThreadSafe(lblV1, "Text", b[5]);
SetControlPropertyThreadSafe(lblV2, "Text", b[6]);
SetControlPropertyThreadSafe(lblV3, "Text", b[7]);
SetControlPropertyThreadSafe(lblI1, "Text", b[8]);
SetControlPropertyThreadSafe(lblI2, "Text", b[9]);
SetControlPropertyThreadSafe(lblI3, "Text", b[10]);
SetControlPropertyThreadSafe(lblLevelPercent, "Text", b[11]);
SetControlPropertyThreadSafe(lblLevelValue, "Text", b[12]);
}
}
FillLstMsg(data);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
答案 0 :(得分:2)
当你做一段时间(true)时,你应该总是在那里添加Thread.Sleep(x)
。这会阻止循环变成紧凑的循环并占用你的CPU。
你只需要睡几毫秒,这就足够了。
至于内存消耗,我怀疑你可能在某处泄漏。还要考虑当CPU非常繁忙时,.NET框架将推迟垃圾收集,直到它不会对系统产生影响(即CPU使用率较低),或者系统内存不足。
当您添加Thread.Sleep时,可能会发生垃圾收集,并且内存使用率将保持稳定。
答案 1 :(得分:2)
基本上我认为你的做法是错误的。
您如何说收到的数据大小? 第一个数据包消息何时结束,另一个数据包消息何时开始? 你知道你的完整数据包消息有多大吗?
在接收来自另一端的数据包时,您应该仔细验证这些问题。
我在TCP实现上继承的一个常见做法是首先发送即将发送的数据包大小,然后根据该数据包大小处理该消息。这将为您提供出色的灵活性,从而创建更强大的TCP实施。如果你这样做,你可以随意发送任意数量的数据包而不会崩溃。
我也看到你搞砸了演示代码和接收数据代码。 您应该创建一个单独的类库来处理所有TCP通信操作, 并将收到的数据扔到消费者应用程序中。
Nito Async库对我来说是一个非常好的起点。你可以看到他在做什么,虽然它是太先进的技术和真正优秀的代码,你可以抓住基本的想法。
从他博客中的这个漂亮的解释开始,然后在codeplex中捕获代码。我现在看到他更新了一些东西,所以你可以把所有的努力都花在你的代码上,如果它适合你的话,甚至是他的代码:)
http://nitoprograms.blogspot.com/2009/04/tcpip-net-sockets-faq.html
快乐阅读!