My code first sends a byte count (8 bytes) so the receiver knows exactly how much to expect. This works flawlessly. Subsequent transmissions would sometimes get everything, but with large records (I'm sending object(s) serialized as XML) the data would often get truncated.
I tried:
Expand|Select|Wrap|Line Numbers
- Dim RxSize as Integer = receiveBufferLength(networkStream)
- Dim RxBytes(RxSize) as Byte
- Do While tcpClient.Available < RxSize
- Threading.Thread.Sleep(100)
- End While
- RxBytes = networkStream.Read(RxBytes, 0, RxSize)
What I found is that once the tcpClient.Available bytes stopped incrementing I had go get them and then the underlying socket would begin adding new bytes to the buffer. A secondary read would get the rest.
I tried setting the tcpClient.ReceiveBufferSize to RxSize - that did not help. I also set tcpClient.NoDelay=True - again no help...
This seemed confusing but here is the code I wound up working out...
Expand|Select|Wrap|Line Numbers
- ' Get the stream
- Dim networkStream As NetworkStream = tcpClient.GetStream()
- 'get the buffersize and set it from the data in the first transmission
- Dim RxSize As Integer = receiveBufferLength(networkStream)
- tcpClient.ReceiveBufferSize = RxSize
- ' Read the stream into a byte array
- Dim rxBytes(rxSize) As Byte
- Dim rxBits(0) As Byte
- Dim iBits As Integer = 0
- Dim iPos As Integer = 0
- Dim Timeout As Integer = 0
- While iPos < rxSize
- iBits = tcpClient.Available
- ReDim rxBits(iBits)
- networkStream.Read(rxBits, 0, iBits)
- rxBits.CopyTo(rxBytes, iPos)
- iPos += (rxBits.Length - 1)
- Threading.Thread.Sleep(100)
- Timeout += 1
- If Timeout > 20 Then Exit While
- End While
So my question is:
what do people on this forum think of this approach? Does anyone have an idea for more efficient code?