2017-03-29 10 views
-1

クライアントがそのスクリーンショットをキャプチャしてTCPソケット経由でサーバに送信するTCPクライアント - サーバプログラムを開発しています。サーバーは画像を画像ボックスに表示します。今のところ、クライアントとサーバー間のイメージ転送はうまくいきますが、画像は画像ボックスに表示されません。画像ボックスにTCPソケットからの画像が表示されない

サーバー側のコード:

private void startListening() 
    { 

     //label1.Text = "Server is starting..."; 
     Console.WriteLine("Server is starting..."); 
     byte[] data = new byte[1024]; 
     IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 9050); 

     Socket newsock = new Socket(AddressFamily.InterNetwork, 
         SocketType.Stream, ProtocolType.Tcp); 

     newsock.Bind(ipep); 
     newsock.Listen(10); 
     //label1.Text="Waiting for a client..."; 

     Socket client = newsock.Accept(); 
     IPEndPoint newclient = (IPEndPoint)client.RemoteEndPoint; 
     //label1.Text = "Connected to client."; 

     while (true) 
     { 
      data = ReceiveVarData(client); 
      MemoryStream ms = new MemoryStream(data); 
      try 
      { 
       lock (this) 
       { 
        Image img = Image.FromStream(ms); 
        pictureBox1.Image = img; 
        pictureBox1.Invoke((MethodInvoker)delegate 
        { 
         pictureBox1.Refresh(); 
        }); 
       } 
      } 
      catch (ArgumentException e) 
      { 
       Console.WriteLine("something broke"); 
      } 


      if (data.Length == 0) 
       newsock.Listen(10); 
     } 
     //Console.WriteLine("Disconnected from {0}", newclient.Address); 
     client.Close(); 
     newsock.Close(); 
     ///////////////////////////////////////////// 

    } 

    private byte[] ReceiveVarData(Socket client) 
    { 
     int total = 0; 
     int recv; 
     byte[] datasize = new byte[4]; 

     recv = client.Receive(datasize, 0, 4, 0); 
     int size = BitConverter.ToInt32(datasize, 0); 
     int dataleft = size; 
     byte[] data = new byte[size]; 


     while (total < size) 
     { 
      recv = client.Receive(data, total, dataleft, 0); 
      if (recv == 0) 
      { 
       break; 
      } 
      total += recv; 
      dataleft -= recv; 
     } 
     return data; 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     var t = new Thread(startListening); 
     t.IsBackground = true; 
     t.Start(); 
    } 

クライアント側コード:私はあなたの問題は、あなたがネットワークスレッドからGUIコンポーネントを操作しようということかもしれないと思う

static void Main(string[] args) 
    { 
     byte[] data = new byte[1024]; 
     int sent; 
     IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9050); 

     Socket server = new Socket(AddressFamily.InterNetwork, 
         SocketType.Stream, ProtocolType.Tcp); 

     try 
     { 
      server.Connect(ipep); 
     } 
     catch (SocketException e) 
     { 
      Console.WriteLine("Unable to connect to server."); 
      Console.WriteLine(e.ToString()); 
      Console.ReadLine(); 
     } 
     while (true) 
     { 

      Bitmap bmp = captureImage(); 

      MemoryStream ms = new MemoryStream(); 
      // Save to memory using the Jpeg format 
      bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Png); 

      // read to end 
      byte[] bmpBytes = ms.ToArray(); 
      bmp.Dispose(); 
      ms.Close(); 

      sent = SendVarData(server, bmpBytes); 

      //Console.WriteLine("Disconnecting from server..."); 
     } 

    } 

    private static Bitmap captureImage() 
    { 
     Bitmap bmpScreenshot = null; 
     try 
     { 
      //Create a new bitmap. 
      bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, 
              Screen.PrimaryScreen.Bounds.Height, 
              PixelFormat.Format32bppArgb); 

     } 
     catch (Exception ex) 
     { 
      Console.WriteLine("Image covertion exception: " + ex); 
     } 
     return bmpScreenshot; 
    } 

    private static int SendVarData(Socket s, byte[] data) 
    { 
     int total = 0; 
     int size = data.Length; 
     int dataleft = size; 
     int sent; 

     byte[] datasize = new byte[4]; 
     datasize = BitConverter.GetBytes(size); 
     sent = s.Send(datasize); 

     while (total < size) 
     { 
      sent = s.Send(data, total, dataleft, SocketFlags.None); 
      total += sent; 
      dataleft -= sent; 
     } 
     return total; 
    } 
} 

答えて

0

このコード:

lock (this) 
{ 
    Image img = Image.FromStream(ms); 
    pictureBox1.Image = img; // Access from network thread to GUI component 
    pictureBox1.Invoke((MethodInvoker)delegate 
    { 
     pictureBox1.Refresh(); 
    }); 
} 

私も見つけの
// No lock here - it's not needed 
// The image data is created on the network thread, it get's captured 
// by the closure and will only get applied on the UI thread 
// If this also doesn't work you might try to capturing the MemoryStream 
// and transfer that to the GUI thread 
Image img = Image.FromStream(ms);  
pictureBox1.Invoke((MethodInvoker)delegate 
{ 
    pictureBox1.Image = img; 
    pictureBox1.Refresh(); 
}); 

いくつかのマイナーな問題:

  • あなたは完全にendOfStream(recv == 0)を処理しません。その場合は、受信を停止する代わりに、不完全に受信した画像をGUIに渡そうとします。
  • ストリームとクリーンアップから例外が発生した場合は、キャプチャしていません。つまり、受信スレッドがクラッシュする可能性があります。 try/catch/finallyの使用を検討してください。そして/またはあなたのソケットの寿命を管理するusing
  • 4バイトのバイトを送受信する際に、すべてのバイトが受信され、送信されたかどうかはチェックしていません。
+0

デバッグ中に、クライアント側からのすべてのバイトがサーバー側で損失なしで受信されていることがわかりました。また、ピクチャボックスにビットマップオブジェクトを割り当てることもできますが、イメージは表示されません。 –

関連する問題