Only one byte is read when reading just now opened SerialPort

c#, serial-port

Solution

Because at the moment of reading, the other bytes didn't arrive, it will read only one byte because only one is there in the queue. So if at least one byte is there it won't wait for the required number of bytes since timeout has happened but it won't throw and exception. If none is there it will throw timeout exception. Therefore you should try reading until you read as many bytes as you need (10 in your case). You can try with something like this:

int count = 0;
var read = new byte[10];
while ((count += port.Read(read, count, read.Length - count)) != read.Length) ;

but what if timeout happens, maybe this can strengthen the code:

int count = 0;
var read = new byte[10];
while (count < read.Length)
{
    try
    {
        count += port.Read(read, count, read.Length - count);
    }
    catch (TimeoutException te)
    {
        //maybe increase ReadTimeout or something, use exponential backoff, your call
    }
}

Problem

Strange issue. When I read from com-port with `SerialPort.Read()`, then if data arrive, only one byte is read on the first call, disregards of `count` parameter and number of bytes available within timeout. All further readings are ok, only very first has problem Using `SerialPort.DiscardInBuffer()` or close/open (reopen) com-port will again cause the problem of the first reading. Here is some code: ``` var port = new SerialPort(); port.PortName = "com2"; port.BaudRate = 9600; port.WriteTimeout = 1000; port.ReadTimeout = 1000; port.Open(); // ... send some data first var read = new byte[10]; if (port.Read(read, 0, read.Length) != read.Length) { // always here at first reading no matter what } // ... send some data again if (port.Read(read, 0, read.Length) != read.Length) { // not here anymore (unless error) } ``` Issue doesn't appears if specified amount of data is already available to read when `Read()` is called. Some explanation. `Read()` is synchronous reading. It will return when specified amount of data is received or timeout is expired. As it seems, `TimeoutException` will be only thrown if zero bytes are received. If timeout is expired before requested amount of data is read, function will return number of bytes read. Thus, return value has to be compared to requested to see if reading was ok. But very first call has a problem: If 0 bytes has arrived during timeout, then first call correctly waits for timeout and trigger TimeoutException. If at least 1 byte has arrived, then function immediately ends, ignoring timeout and requested number of bytes to read altogether. This is how I see it. Am I wrong? What should I do? Some more tests. Inserting `Thread.Sleep()` to ensure that when `Read()` is called, there will be all data available, will make problem to disappears. Logically, let's add sleep for only first call. Yay. What???? The problem now appears with second call and only second call. In other word problem appears with the first Read() what will not have all data available but only once.

Original source