I have a method to receive a sequence of serial data message in a while loop. Each of them could be more than 100 bytes but less than 2048 bytes. Most of them are about 1000 bytes.
public int RecvSerialData(ref byte[] respBuf, int delay)
{
var recvBuf = new byte[2048];
var count = m_serial.BytesToRead;
if (count > 0)
{
var sw = new Stopwatch();
sw.Restart();
while (sw.ElapsedMilliseconds < delay)
{
}
count = m_serial.BytesToRead;
m_serial.Read(recvBuf, 0, count);
// Do something with respBuf
return count;
}
return -1;
}
The problem is I don’t know the exact length of each message since the communication protocol does not contain it.
So when I transfer a delay to this method, it would waste a large of time if the delay is too long. But if the delay is too short, the message would not receive completely which would cause an issue.
Is there some better method to receive variable length serial data?
- The client would not send next message until I reply the message before, so there is no risk to receive the next message even if I transfer a very long delay here.
- As a matter of fact, I spent over 65 seconds to receive all of those serial messages if I transfer delay of 30ms, and all messages are received completely.
- And spent less than 20 seconds if I transfer delay of 5ms, but some messages are not received completely and caused some issues.
- My project is a Winform project with .NET Framework 4.6.
Protocol:
- Host(1 byte, fixed 0x02)
- Step(1 byte, fixed 0x35 at this moment)
- InfoA(1 byte)
- InfoB(2 bytes)
- ACK/NAK(1 byte)
- Error Code(4 bytes)
- InfoC(2 bytes)
- Body(0-2000 bytes)
Info areas are used for transfer some info of client, similar to Host and Step. There are no length or crc in Info areas.
Edit:
Thanks for all. I found a better way. Not perfect, but good enough for me.
public int RecvSerialData(ref byte[] respBuf)
{
var recvBuf = new byte[2048];
var count = m_serial.BytesToRead;
if (count > 0)
{
var offset = 0;
m_serial.Read(recvBuf, offset, count);
offset += count;
while(true)
{
count = m_serial.BytesToRead;
if(count == 0)
{
break;
}
m_serial.Read(recvBuf, offset, count);
offset += count;
Thread.Sleep(5);
}
// Do something with respBuf
return offset;
}
return -1;
}
It would sleep 5ms or 10ms for most data, good enough for me.
WangDaChui is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
10