I have a TCP server (a line scan camera) which based on specifications sends me the image data. The image data is in form of 1D byte array. The number of bytes sent by the camera is known but it can vary based on the specification so sometimes it will be a very large number and sometimes a small one. I am using Networkstream.Read to get the bytes and trying to store it into an array.
The problem is that it sends me in packets. I need a way that all the data sent from the stream is stored in a single byte array which I can then use and convert it to an image.
This is the code I have been using now. I am still new to VB. I tried storing the data into arrays and then append them but somehow VB does not provide that functionality.
Dim imageData(numberOfColumns * numberOfLines - 1) As Byte
Dim bytesReceived =
Dim bytesReceivedTotal = 0
Dim bytesToRcv = numberOfColumns * numberOfLines
Dim imageFragment() As Byte
Dim rcvbytes(8092) As Byte 'tried socket.receivebuffersize too
Dim readCount = 0
Do
bytesReceived = clientStream.Read(rcvbytes, 0, rcvbytes.Length)
bytesReceivedTotal += bytesReceived
rcvbytes.CopyTo(imageData, (bytesReceivedTotal - bytesReceived))
Loop Until bytesReceivedTotal = bytesToRcv
The problem with this code is that the length of the rcvbytes does not change for the last read. Is there a way that I can store all the data from the stream in a single byte array? the size of the bytes sent by the server is obtained by: (numberOfLines * numberOfColumns)
UPDATE #2: WORKING CODE
Do
Dim bytesWanted As Integer = bytesReceivedTotal + 8092
Dim bytesToRead As Integer = If(bytesWanted > imageData.Length, imageData.Length - bytesReceivedTotal, 8092)
bytesReceived = clientStream.Read(imageData, bytesReceivedTotal, bytesToRead)
bytesReceivedTotal += bytesReceived
Loop Until bytesReceivedTotal = bytesToRcv
Since TCP is a stream-based protocol, the only way to surely put all expected data (an entire "message") into a single array is to keep calling NetworkStream.Read()
until you've read the sufficient amount of bytes.
I tried storing the data into arrays and then append them but somehow VB does not provide that functionality.
That is not true. There are several ways you can concatenate chunks of data. You could for instance use a List(Of T)
.
However in your case the answer is actually right under your nose. If you take a look at the NetworkStream.Read()
documentation you can see that the second parameter (called offset
) specifies "The location in buffer
to begin storing the data to" - where buffer
is the byte array you specify as the first parameter.
If you give the offset
parameter the number of already read bytes it will append the new bytes after the already received ones, in the array. Also keep in mind that you do not want to read too much if you're getting close to the end of the array.
Dim bytesWanted As Integer = bytesReceivedTotal + 8092
Dim bytesToRead As Integer = If(bytesWanted > imageData.Length, imageData.Length - bytesReceivedTotal, 8092)
clientStream.Read(imageData, bytesReceivedTotal, bytesToRead)