2017-02-06 15 views
0

私はtcpclient/networkstream経由で画像(特にスクリーンショット)を送信しています。受信側で画像のバイトを正しく読み取るには、画像の長さを知る必要があります。私がするつもりは、画像サイズのバッファの最初の6バイトを保存することです(それは決して6つの数字を超えないように思われるので)。その後、残りのバッファをイメージとして保存します。私が抱えている問題は、最初の6バイトしか読み込めないことです。NetworkStreamから最初の6バイトを読み込みますか?

サーバコード

 int data = 0; 

     byte[] readBuffer = new byte[getSelectedClient().ReceiveBufferSize]; 

     **data = stream.Read(readBuffer, 0, 5, readBuffer.Length);** <-- sort of thing im trying to do 

     string pictureSize = Encoding.ASCII.GetString(readBuffer, 0, data); 

     Console.WriteLine(pictureSize); //for debugging purposes 

     string x = new Random().Next().ToString(); 

     FileStream f = new FileStream(x + ".bmp", FileMode.Create, FileAccess.Write); 

     while (new FileInfo(x + ".bmp").Length != Convert.ToInt32(pictureSize)) 
     { 
      **data = stream.Read(readBuffer, 6, readBuffer.Length);** <-- then it would read from the 6th byte, which would be the start of the image 
      f.Write(readBuffer, 0, data); 
     } 

     f.Close(); 

     Process.Start(x + ".bmp"); 

     screenShotBTN.Enabled = true; 

あなたが実装しているどのようなクライアントコード

MemoryStream ms = new MemoryStream(); 
Bitmap bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); 
Graphics graphics = Graphics.FromImage(bitmap); 
graphics.CopyFromScreen(0, 0, 0, 0, bitmap.Size); 
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); 
       writeToStream(combineBytes(Encoding.ASCII.GetBytes(ms.Length.ToString()), ms.ToArray())); 
ms.Close(); 


public static byte[] combineBytes(byte[] b1, byte[] b2) 
    { 
     byte[] b3 = new byte[b1.Length + b2.Length]; 
     Array.Copy(b1, 0, b3, 0, b1.Length); 
     Array.Copy(b2, 0, b3, b1.Length, b2.Length); 
     return b3; 
    } 

答えて

1

は長同一キーメッセージです。

覚えておくべきことは、ネットワークストリームから読み取っているときに、探しているすべてのバイトをすぐに受信するとは限りません(ほとんどの場合、ローカルですべてをテストしていますが、あなたは最悪の場合に1バイトしか受け取らない可能性があります)。

したがって、状態(待っている長さ、待っているペイロード)に入る必要があります。 その後、待機中にバイトを読み込み、そのデータをバッファに蓄積します。あなたの長さ(あなたのケースでは6バイト)を取得したら、待機状態のpayloadに切り替えることができます。次に、ペイロードが完全になるまで、セカンダリバッファに読み込みます。

メッセージフレーミングに関するStephen Clearyの記事を読む価値があります。私はこれらを読んでネットワーキングについてたくさん学んでいます。

http://blog.stephencleary.com/2009/04/sample-code-length-prefix-message.html

0

私は自分自身で問題を解決しました。

サーバー

int data = 0; 

byte[] readBuffer = new byte[getSelectedClient().ReceiveBufferSize]; 

data = stream.Read(readBuffer, 0, 6); //only read first 6 

string pictureSize = Encoding.ASCII.GetString(readBuffer, 0, data); 

Console.WriteLine(pictureSize); //for debugging purposes 

string x = new Random().Next().ToString(); 

FileStream f = new FileStream(x + ".bmp", FileMode.Create, FileAccess.Write); 

while (new FileInfo(x + ".bmp").Length != Convert.ToInt32(pictureSize)) 
{ 
    data = stream.Read(readBuffer, 0, readBuffer.Length); 
    f.Write(readBuffer, 0, data); 
} 

f.Close(); 

Process.Start(x + ".bmp"); 

screenShotBTN.Enabled = true; 

クライアントコード

MemoryStream ms = new MemoryStream(); 
Bitmap bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); 
Graphics graphics = Graphics.FromImage(bitmap); 
graphics.CopyFromScreen(0, 0, 0, 0, bitmap.Size); 
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); 
Console.WriteLine(ms.Length.ToString()); 
writeToStream(combineBytes(Encoding.ASCII.GetBytes(ms.Length.ToString()), ms.ToArray())); 
ms.Close(); 
+0

ちょうど先端、あなたがネットワークを介してデータを送信しているとき、あなたはバイトの代わりに文字を送信することができます。ワイヤ上に表示される整数(int.minvalue - > int.maxvalue)は4バイトです。 –

+0

あなたは精巧にできますか?(私はあなたが意味することについて少し混乱しています。私はそのようにもっと良く学ぶように見えるので、例が助けになります) – rrrrrrrrrrrrrrrr

+0

あなたのwirteToStreamでは長さを文字列に変換しています。その数字を表す文字列のバイトを取得します。 文字列に変換する代わりにBitConverter.GetBytes(int)を使用してください。 Intをバイトに変換すると、常に4になります。 –

関連する問題