2016-10-05 77 views
0

我有一台基于规格的TCP服务器(行扫描摄像机)向我发送图像数据。图像数据采用1D字节数组形式。相机发送的字节数是已知的,但它可以根据规格而有所不同,所以有时它会是一个非常大的数字,有时是一个很小的数字。我正在使用Networkstream.Read获取字节并尝试将其存储到数组中。获取来自networkstream的所有字节。读入单字节数组

的问题是,它向我发送的数据包。我需要一种方式,将从流中发送的所有数据存储在单个字节数组中,然后我可以使用它并将其转换为图像。

这是我现在使用的代码。我还是VB新手。我试图将数据存储到数组中,然后追加它们,但不知何故VB不提供该功能。

 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 

该代码的问题在于上次读取时rcvbytes的长度没有变化。有没有一种方法可以将流中的所有数据存储在单个字节数组中? (numberOfLines * numberOfColumns)

更新#2:工作代码

  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 

回答

0

由于TCP是一个面向流的协议,只有这样,才能可靠地把由服务器发送的字节数的大小由所得所有预期的数据(整个“消息”)整合到一个数组中将继续调用NetworkStream.Read(),直到读取足够的字节数为止。

我试图将数据存储到数组中,然后追加它们,但VB以某种方式不提供该功能。

这是不正确的。有几种方法可以连接数据块。你可以例如使用List(Of T)

不过你的情况其实答案就在您的鼻子底下。如果您看一下NetworkStream.Read() documentation,则可以看到第二个参数(称为offset)指定buffer中的位置开始将数据存储到” - 其中buffer是您指定的第一个参数的字节数组。

如果你给offset参数的数量已经读取的字节已经收到的个案后,将追加新的字节,在数组中。另外请记住,如果您接近数组的末尾,则不需要太多读取。

Dim bytesWanted As Integer = bytesReceivedTotal + 8092 
Dim bytesToRead As Integer = If(bytesWanted > imageData.Length, imageData.Length - bytesReceivedTotal, 8092) 

clientStream.Read(imageData, bytesReceivedTotal, bytesToRead) 
+0

我这样做是使用另一种方法几分钟前,但你的代码完全是有道理的。我做的方式是使用内存流将数据写入缓冲区,并且工作正常。哪一个更好? PS:我似乎无法正确粘贴代码。使用计算器 – ShamsRKhan

+0

第一次@ShamsRKhan:我会消耗比你更少的内存,由于使用'MemoryStream'两家超市,你给它在内存中的新副本中的数据,但是当你调用'MemoryStream.ToArray也创造了一个全新的数组()',而我的写信给你主阵列直接(因此它也快一点)。 - 也请在测试之前将其标记为答案。最好先验证它是否有效。 –

+0

@ShamsRKhan:复制代码有时可能有点棘手......只需通过拖动代码块外的选择来尝试全部选中它。 –