2016-10-05 38 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:複製代碼有時可能有點棘手......只需通過拖動代碼塊外的選擇來嘗試全部選中它。 –