[英]Write() and Read() raw bytes from NetworkStream, data is difference at some bytes
我已經寫了一些代碼,用於在發送之前使用大小為KNOWN的NetworkStream發送byte []數組,但是在某些位置發送的數據和接收的數據有所不同。
MAXSIZE是我要發送的數據的已知大小。
public static void SendBytes(TcpClient clientSocket, byte[] outStream)
{
Debug.WriteLine("SendBytes() number of bytes: " + outStream.Length.ToString());
NetworkStream serverStream = clientSocket.GetStream();
serverStream.Write(outStream, 0, outStream.Length);
//serverStream.Flush();
}
public static byte[] ReceiveBytes(TcpClient clientSocket, int MAX_SIZE)
{
Debug.WriteLine("[" + DateTime.Now.ToString("G") + "] - " + "ReceiveBytes() started.");
NetworkStream networkStream = clientSocket.GetStream();
byte[] bytesFrom = new byte[MAX_SIZE];
clientSocket.ReceiveBufferSize = MAX_SIZE;
networkStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize);
Debug.WriteLine("[" + DateTime.Now.ToString("G") + "] - " + "ReceiveBytes(), received number of raw bytes: " + bytesFrom.Length.ToString());
return CommonUtils.SubArray(bytesFrom, 0, MAX_SIZE);
}
如果發送數據(十六進制字節):a7 fc d0 51 0e 99 cf 0d 00,則接收到的數據為:a7 fc d0 51 0e 99 cf 0d 53
由於數據包的結構化,很可能您會看到垃圾。 TCP僅保證正確的字節將以正確的順序到達(或流失敗)-它沒有說明它們到達的塊 。 因此, 至關重要的是:
Read
捕獲返回值,並且僅處理任何塊中的那么多字節 如果您的消息始終是固定大小,則“ 2”將變為“緩沖數據,直到我至少有N個字節,然后以N個塊的形式處理數據,保留剩下的所有內容,然后恢復緩沖”。 但是在一般情況下,它可能是“緩沖,直到我看到一個前哨值,例如換行”,或者是“緩沖,直到我有一個完整的標頭,然后解析標頭以查看期望的數據量,然后緩沖直到我有那么多數據”。
有一些工具和實用程序可幫助簡化幀刪除和處理積壓工作-例如,使用新的“管道” API,它只是檢查管道並告訴管道您要消耗多少(而不是管道)的一種情況。為您提供了一切,並且您現在暫時無法拒絕數據)-但是對於大多數人來說,從Stream
切換到“管道”是相當多的變化。
就您而言,您可以使用:
byte[] bytesFrom = new byte[MAX_SIZE];
int outstanding = MAX_SIZE, read, offset = 0;
while (outstanding > 0 && (read = networkStream.Read(bytesFrom, offset, outstanding)) > 0)
{
offset += read;
outstanding -= read;
}
if (outstanding != 0) throw new EndOfStreamException();
這將創建一個讀取循環,該讀取循環將完全填充bytesFrom
,否則將失敗並發生異常。
Stream.Read
返回一個值,該值指示實際讀取了多少數據。 絕不保證與您要求的金額相同。 忽略此值會帶來危險。
如果您樂意為整個流分配內存,為什么不只復制到MemoryStream
並從中獲取全部緩沖區呢? Stream.CopyTo
和Stream.CopyToAsync
是很好的高級抽象,使此操作變得容易。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.