2017-07-31 1 views
0

私がコードを実行しているときにコードが正常に機能するが、正常に実行されているときに不正なデータが読み込まれるという問題があります。しかし、問題が起こっている可能性があると思ったが、NetworkStream.Read()がブロックされているはずです。また、スレッドを1000msのスリープ状態にしてテストしました。ループの最初の反復処理後に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を認識していないようだ、それは正しく、それを最初に実行する時間の長さや画像を受信することです問題自体ではありません。

ありがとうございます!

EDIT: は、だから私は、問題を絞り込むと、それを取得するために、画像を取得するためにNetworkStream.Write()を使用してnetworkStream.Read()私のTelnetコールの間にいくつかの人工的な遅延に追加することによって、それを修正するために管理しなかった、しかし、このソリューションは厄介であり、私は希望まだこの問題が起こっている理由を知りたい

+0

=!それはどのように写真に収まるのでしょうか? –

+0

配列は実際には空ではありません - ヌルターミネーターを追加するのは、telnet経由では来ないので、 'Encoding.ASCII.GetString()'が追加されているかどうかわからないからです。それぞれの読み取り値は '\ r \ n'を読むまで1サイクルのバッファによって相殺されます。その文字列を解析して整数を取り出します。 –

+0

.NETの文字列は、実際にはヌルターミネータを持っていません(interop用の文字列の後にnullバイト*がありますが、文字列)、それはCのことです。 .NET文字列には、長さ接頭辞が付けられます。いずれにしても、 'Read'は要求されたバイト数を*まで返します。戻り値は、実際に何バイト読み込まれたかを示します。必要なだけ正確にデータを取得するまで、呼び出しを続ける必要があります。あなたが持っている方法では、その時点でどのようなデータが管理されていても、それだけを読んだだけで、その後の読み込みはすべて予測不可能な動作になります。 – Luaan

答えて

1

Read()操作は実際に読み取られたバイト数を返します。 があり、読み取るデータがである場合にのみブロックし、countパラメーターで指定されたバイト数より少ないバイト数を戻すことができます。

あなたは簡単にループ内でこれを置くことによってこの問題を解決することができます?あなたは空の配列に `GetString`を適用している

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 Forms Picture Boxにイメージを正常に表示しています。読み込みと 'NetworkStream.Write()'の間に数百ミリ秒間スリープするように強制することで一時的に問題を解決しました。電話で実際にTelnetサーバに画像の入力を促します –

+0

ああ、私は潜在的な欠陥を見て、あなたの問題を解決できる結論に飛びました。データがどのように不正な形になっているのか、一見無作為なのかを知ることができます。 –

+0

正しいデータは、バイト単位のイメージの長さだけをASCII形式で示しています。長さで撮影されている現在の画像は82998バイトです。 'len'の長さは5です(いくつかの先行ゼロと一緒に、' len'の全長を読み込み直後に約8にします)。最初の実行後の 'len'の間違った長さは7500から15000の間であり、主に1と5の間のバイト値で満たされます(そしていくつかの大きな値のスパッタリング) –

関連する問題