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);
}
}
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!