title: VB.Net SerialPort reads are returning fragmented sets of data
body: <h2>The Problem</h2>
  
  <p>I have a USB device which creates a Virtual Serial Port on Windows. I am using VB.Net to write and read from the port. My device responds with specific sized set of bytes, but I am finding that SerialPort.Read(byte-array,offset,number-bytes) does not return the full number-bytes but it also does not timeout or generate an exception. Repeated calls return additional fragments (up to 3 calls required). I do not understand why this read method behaves the way it does? Does it think the requested number of bytes is only a suggestion? :-). I would expect that it would wait to fulfill the entire request, unless it timesout first. </p>
  
  <p>Python code using pySerial <strong>does not</strong> have the same problem.</p>
  
  <p><strong>So, what am I doing wrong here? Am I expecting too much?</strong></p>
  
  <h2>Some scenarios are:</h2>
  
  <ol>
  <li>I write a command to the port and expect to get 4 bytes in response. I get 1 byte first and then 3 bytes on the subsequent call.</li>
  <li>I write a command and expect 21120 bytes in response. I get 1, 12671 and then 8448 bytes in 3 calls to read from the port.</li>
  </ol>
  
  <h2>Here are some excerpts from my code:</h2>
  
  <pre><code>Private Sub SetupVirtualSerialPort()
    Dim portName As String = "COM" + (m_DeviceContext * -1).ToString
    Const baud As Int32 = 9600    '7680000
    Const parity As Parity = parity.None
    Const databits As Int32 = 8
    Const stopbits As StopBits = stopbits.One
    m_SerialPort = New SerialPort(portName, baud, parity, databits, stopbits)
    m_SerialPort.WriteTimeout = VSPtimeout
    m_SerialPort.ReadTimeout = VSPtimeout
    m_SerialPort.ReadBufferSize = 2 * RETURN_BUFFER_SIZE
    m_SerialPort.WriteBufferSize = 2 * COMMAND_BUFFER_SIZE
    m_SerialPort.Open()
  
    ' Register event handlers
    AddHandler m_SerialPort.ErrorReceived, AddressOf m_DriverInterface.Handle_VSP_Error
  End Sub
  
  
  Public Function WriteReadVSPort(ByVal commandLength As Int32, ByVal returnLength As Int32)             As Int32
  
    Const RetryLimit As Int32 = 5
    Dim NumberRetries As Int32 = 0
    Dim Offset As Int32 = 0
    Dim ExceptionOccurred As Boolean = False
    Dim NumberBytes As Int32 = 0
  
    Try '  Writing
      m_SerialPort.Write(m_CommandBuffer, 0, commandLength)
    Catch exc As InvalidOperationException
      MessageBox.Show("InvalidOperationException", Application.ProductName)
      ExceptionOccurred = True
    Catch exc As TimeoutException
      MessageBox.Show("TimeoutException", Application.ProductName)
      ExceptionOccurred = True
    End Try
  
    If Not ExceptionOccurred Then
  
      Try ' Reading
  
        ' Working around a problem here: reads are returning fewer 
        ' bytes than requested, though not signalling a timeout exception.
        ' Therefore, we retry if we got fewer bytes than expected, up to five times.
        While NumberRetries &lt; RetryLimit And returnLength &gt; Offset
  
          NumberBytes = m_SerialPort.Read(m_ReturnBytes, Offset, returnLength - Offset)
          Offset += NumberBytes
          NumberRetries += 1
          If returnLength &lt;&gt; NumberBytes Then
            System.Diagnostics.Debug.Print("Number of bytes read (" &amp; NumberBytes &amp;
              ") not what was requested (" &amp; returnLength &amp; "). Accumulated " &amp; Offset)
          End If
  
        End While
  
      Catch exc As InvalidOperationException
        MessageBox.Show("InvalidOperationException", Application.ProductName)
        ExceptionOccurred = True
      Catch exc As TimeoutException
        MessageBox.Show("TimeoutException", Application.ProductName)
        ExceptionOccurred = True
      End Try
  
    If ExceptionOccurred Then
      Return 1
    Else
      Return 0
    End If
  
  End Function
  </code></pre>
  
  <p>Thank you.</p>