2017-07-31 87 views
0

我遇到了一個問題,即當我單步執行代碼時會按預期工作,但在正常運行時會讀取不正確的數據。我認爲問題可能是時機NetworkStream.Read()應該是封鎖,我也測試了這個線程睡1000毫秒(超過足夠的時間和更多的時間比我正在步入時)。NetworkStream.Read()在循環的第一次迭代後沒有正確讀取

代碼的目的(以及逐步執行時的操作)是將位圖圖像讀入緩衝區,該緩衝區前面是一個以字節爲單位的圖像大小的字符串,後跟一個回車符和一個新行。我相信問題在於閱讀陳述,但我無法確定。下面的代碼包含在一個更大的循環中,也包含Telnet讀取,但是我沒有遇到這些問題,它們只讀取ASCII字符串,沒有二進制數據。

List<byte> len = new List<byte>(); 
byte[] b = new byte[2]; 
while (!Encoding.ASCII.GetString(b).Equals("\r\n")) 
{ 
    len.Add(b[0]); 
    b[0] = b[1]; 
    b[1] = (byte)stream.ReadByte(); 
} 
len = len.FindAll(x => x != 0); 
len.Add((byte)0); 
string lenStr = Encoding.ASCII.GetString(len.ToArray()); 
int imageSize = int.Parse(lenStr); 
byte[] imageIn = new byte[imageSize]; 
stream.Read(imageIn, 0, imageSize); 
using (MemoryStream g = new MemoryStream(imageIn)) 
{ 
    g.Position = 0; 
    bmp = (Bitmap)Image.FromStream(g); 
} 

,與代碼發生實際問題是,它正確地運行它的第一次接收的長度和圖像,但是它似乎沒有認識到\r\n在連續讀取,然而,這可能僅是一種症狀而不是問題本身。

在此先感謝!

編輯: 沒等我下來縮小的問題,並設法通過使用NetworkStream.Write()檢索圖像和networkStream.Read()檢索它在我的Telnet通話之間一些人爲的延遲相加來解決它,但是這種解決方案是凌亂的,我會仍然想知道爲什麼會發生這個問題

+0

你申請'GetString'一個空數組=!這是如何融入圖片? –

+0

該數組實際上不是空的 - 我只是添加了一個空終止符,因爲這不是通過telnet發送的,我不確定是否在'Encoding.ASCII.GetString()'中添加了一個。它添加了每個讀取值由單個週期的緩衝區偏移,直到我讀取「\ r \ n」。然後我解析該字符串以從中取出一個整數 –

+0

.NET字符串不*真*有一個空終止符(在字符串之後有一個空字節*,用於互操作目的,但不是真正的部分字符串),這是一個C的東西。 .NET字符串以長度爲前綴。在任何情況下,'Read'都會返回*達到*請求的字節數量。返回值告訴您實際讀取了多少個字節 - 您需要一直調用它,直到獲得儘可能多的數據爲止。你擁有它的方式,你只能讀取當時到達的任何數據,其餘的讀取到任何後續的讀取 - 導致相當不可預知的行爲。 – Luaan

回答

1

Read()操作返回實際讀取的字節數。它只在有沒有數據要讀取時纔會阻塞,並且它可以返回較少的字節,如count參數所指定的那樣。

您可以輕鬆地在這個循環中解決這個問題:?

byte[] imageIn = new byte[imageSize]; 
int remaining = imageSize; 
int offset = 0; 
while (remaining > 0) 
{ 
    int read = stream.Read(imageIn, offset, remaining); 
    if (read == 0) throw new Exception("Connection closed before expected data was read"); 
    offset += read; 
    remaining -= read; 
} 
+0

有一點需要注意的是,我正在檢索讀取的第一個圖像的所有數據(我在Windows窗體圖片框中成功顯示圖像,只是在第一個圖像看起來格式錯誤後纔讀取數據。也不是沒有被正確讀取的部分,而是包含圖像大小的頭部。我已經通過強制線程在read和'NetworkStream.Write()之間睡了幾百毫秒來暫時解決了這個問題。電話,實際上提示Telnet服務器的圖像 –

+0

啊,我剛剛看到了潛在的缺陷,並跳到結論,這將解決您的問題。你能比較你收到什麼,你期望?我想知道是否有一個數據格式不正確或者看似隨機的模式。 –

+0

正確的數據表示ASCII中字節的圖像長度。對於當前正在拍攝的圖像長度爲82998字節。 len的長度是5(連同我過濾掉的一些前導零,在讀完之後立即使len的總長度達到8左右)。第一次運行後,'len'的長度不正確,介於7500和15000之間,主要填充1到5之間的字節值(以及幾個較大值的飛濺) –

相關問題