Reputation: 3279
I'm creating a socket-based telemetry app, I use two radio modems to send/receive data, one app sends data via modem 1 and the other program gets data through modem 2, my send interval is one second, it seems that the receiver app (the server) is using most of CPU and RAM resources (99% cpu usage!) and its memory usage increases steadily! so that after some minutes my program almost stops responding and my data is not correct at all, so data cannot be parsed, it seems that my programs receives several copies of the sent data, my original data packet is about 70 bytes, but after some seconds its size increase, I think my receive buffer is full and data is mixed with previous data, I'm looking for some suggestions, here is my receive handler in server program:
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);
}
}
Upvotes: 0
Views: 1359
Reputation: 8626
Basically I think that your approach is wrong.
How can you say the data size sent-received? When is the first packet-message ends and another one starts? Do you know how big is your full packet message is?
These are some issues you should carefully validate while receiving packets from the other end.
A common practise I have inherited on my TCP implementation is first send packet size that is coming and then handle the message based on that packet size. This will give you great flexibillity creating a more robust TCP implementation. If you do this you can then send as many packets as you want one after another without crashes.
I also see that you messed up presentation code with receiving data code. You should create a seperate class library to handle all your TCP communication operations, and throw the received data in the consumer application.
Nito Async library was a very good starting point for me. You could see what he is doing, though is too advanced techniques and real good code in there, you can catch the basic idea.
Start from this beautiful explanation in his blog and then catch the code in codeplex. I see now that he updated some stuff, so you can get all his effort to your code, or even his if it suits to you :)
http://nitoprograms.blogspot.com/2009/04/tcpip-net-sockets-faq.html
Happy reading!
Upvotes: 2
Reputation: 2147
When you do a while(true), you should always add a Thread.Sleep(x)
in there. That stops the loop from becoming a tight loop and consuming your CPU.
You only need to sleep for a few milliseconds, that would be enough.
As for the memory consumption, I suspect that you may have a leak somewhere. Also consider that when the CPU is very busy,garbage collection will be deferred by the .NET framework until it either won't have an effect on the system (i.e. the CPU usage is lower), or the system is running low on memory.
It might be that when you add the Thread.Sleep, garbage collection will happen and the memory usage will stay steady.
Upvotes: 3