3

i'm having a problem with virtual serial ports in C#: when i call the Write function, it automatically throws a TimeOutException, but the client receives the data.

It only happens with virtual ports (i'm using Free Virtual Serial Ports from HDDSoftware, with a bridge COM12<->COM13). I open COM12 with the Visual Studio and the COM13 with Hercules. The application throws the timeout exception but Hercules receives the message.

It doesn't matter if i set 1000ms or 1000000ms of Read/Write port timeout.

Thanks!!

        using (SerialPort port = new SerialPort("COM13"))
        {
            // configure serial port
            port.BaudRate = 9600;
            port.DataBits = 8;
            port.Parity = Parity.None;
            port.StopBits = StopBits.One;
            port.Open();

            port.ReadTimeout = 10000;

            byte[] buffer = Encoding.ASCII.GetBytes("HELLO WORLD");

            try
            {
                port.Write(buffer, 0, buffer.Length);
            }
            catch(TimeoutException)
            {
                Console.WriteLine("Write timeout");
            }

            Console.WriteLine(DateTime.Now.ToString("HH:mm:ss"));
            try
            {
                byte[] buf = new byte[100];
                port.Read(buf, 0, 1);
            }
            catch(IOException)
            {
                Console.WriteLine("Read timeout");
            }
            Console.WriteLine(DateTime.Now.ToString("HH:mm:ss"));
        }

After a few tests (putting the Write into a try-catch), the Read operation also throws a TimeOutException instantly.

This is what i get when run the test. It is supposed to be: 12:16:06 (Read timeout) 12:16:16

enter image description here

dsolimano
  • 8,870
  • 3
  • 48
  • 63
tincho87
  • 349
  • 1
  • 4
  • 12
  • Possibly related (although unanswered at this time): [Timeout exception when writing to a virtual COM](http://stackoverflow.com/questions/18746980/timeout-exception-when-writing-to-a-virtual-com). – vgru Aug 22 '14 at 14:27
  • this could be interesting: http://social.msdn.microsoft.com/Forums/en-US/0289eb48-30d7-434e-b912-ac818672c0b4/issue-with-serialportwrite-timeout?forum=netfxnetcom – jbutler483 Aug 22 '14 at 14:30
  • @Groo yes, i saw this and tried the solutions, but didn't help. – tincho87 Aug 22 '14 at 14:37
  • @jbutler483 thanks, but in this case, the exception is throwed when i call the write function, and i don't know if the exception if because there is a problem with the port or because the port is a virtual com. – tincho87 Aug 22 '14 at 14:40
  • could you poss post some code where it reads/writes the data? – jbutler483 Aug 22 '14 at 14:45
  • @tincho87, also, is the Timeout exception read or write? – jbutler483 Aug 22 '14 at 14:49
  • what values have you set for buffer/offset/count? – jbutler483 Aug 22 '14 at 14:50
  • @jbutler483 i'm using it to send Modbus questions, in this case, ':01031B59000187' (as a byte array). The timeoutexception is triggered by both read and write operations :s – tincho87 Aug 22 '14 at 14:53
  • so it would be **port.write(buffer,0,buffer.Length)** ? (where buffer is the array) - and then with the 'read', you're using **port.read(buffer,0,1)** to read the buffer, and then concatenate it on the other side? – jbutler483 Aug 22 '14 at 14:56
  • @jbutler483 exactly. but the Hercules receives the question. – tincho87 Aug 22 '14 at 14:58
  • try setting the **dataBits** to 8 and **Parity** to none. Have you also stated the port's **name** somewhere else in the program? – jbutler483 Aug 22 '14 at 14:59
  • @jbutler483 tried setting databits to 8 and parity to none, but stills throwing the exception – tincho87 Aug 22 '14 at 15:01

2 Answers2

2
   port.Write(buffer, offset, count);

It is up to the device driver to decide how to implement this. But all the ones I know follow the rule that the underlying WriteFile() call is allowed to return *lpNumberOfBytesWritten < nNumberOfBytesToWrite. Or to put it another way, the write is not "transactional".

A decent mental model is that Write() writes one byte from the buffer at a time, count times. At some point, entirely unpredictable when, writing one more byte will stall when the driver's transmit buffer fills up to capacity and cannot store another byte. Eventually triggering the exception.

So part of the buffer will still make it to the other end. You cannot tell what part from the SerialPort class. A time-out is a gross communication failure that's pretty hard to recover from. If that's a show-stopper then you need to consider writing one byte at a time (fine, serial ports are slow) or pay attention to WriteBufferSize - BytesToWrite to check if the buffer fits and implement your own timeout.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Hi, i tried to write one byte at a time, but at the first write, i get the TimeOutException. In the example added in the question, in Hercules i receive only the "H" from "HELLO WORLD" doing this. – tincho87 Aug 22 '14 at 15:24
  • Hmm, what is the WriteBufferSize and what did you set the WriteTimeout property to? Guidance is to make it 10 times longer than the expected delay in whatever program reads the port. Which can easily be hundreds of milliseconds on a demand-paged virtual memory operating system like Windows or Linux. So don't use less than 5000. – Hans Passant Aug 22 '14 at 15:34
  • The values are the defaults, but tried to set the WriteTimeOut = 10000 and the same. WriteBufferSize to 2048 and the same. I don't know what is happening with virtual ports. – tincho87 Aug 22 '14 at 15:41
  • 1
    The default for WriteTimeout is 0 and should *not* produce a TimeoutException when you write. Clearly this software you are using isn't very reliable. Contact the vendor for support. – Hans Passant Aug 22 '14 at 15:45
0

As Hans Passant said, it was a problem with the Virtual COM software. I tried with Virtual Serial Port from Eltima Software and worked fine!

tincho87
  • 349
  • 1
  • 4
  • 12