TCP发送图像客户端和服务器

本文关键字:服务器 客户端 图像 TCP | 更新日期: 2023-09-27 18:09:49

我有一个客户机应用程序和一个服务器应用程序。客户端应用程序每40毫秒激活此函数:*注意nstream是一个NetworkStream实例。

private void SendScreen(NetworkStream nstream)
    {
        StreamWriter writer = new StreamWriter(nstream);
        ScreenCapture sc = new ScreenCapture();
        System.Drawing.Image img = sc.CaptureScreen();
        MemoryStream ms = new MemoryStream();
        img.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
        byte[] buffer = new byte[ms.Length];
        ms.Seek(0, SeekOrigin.Begin);
        ms.Read(buffer, 0, buffer.Length);
        Console.WriteLine(buffer.Length);
        writer.WriteLine(buffer.Length);
        writer.Flush();
        nstream.Write(buffer, 0, buffer.Length);
    }

这是接收图像的服务器应用程序代码:

private async void ShowImage()
    {
        while (true)
        {
            string num = await reader.ReadLineAsync();
            Console.WriteLine(num);
            int ctBytes = int.Parse(num);
            byte[] buffer = new byte[ctBytes];
            await stream.ReadAsync(buffer, 0, buffer.Length);
            MemoryStream ms = new MemoryStream(buffer);
            Image img = Image.FromStream(ms);
            Bitmap bmp = new Bitmap(img);
            this.Height = bmp.Height;
            this.Width = bmp.Width;
            this.BackgroundImage = bmp;
        }
    }

我想不出任何干扰这些动作的部分。在服务器应用程序的第一次迭代中,一切正常(尽管我看到的是黑屏而不是屏幕截图——但是发送和接收的字节数是匹配的)。在第二次迭代时,当我写入linenum时,它显示jibberish然后停止(因为它不能被解析为int)。

TCP发送图像客户端和服务器

基本上我怀疑你有一个同步问题,当我试图重现你的问题(成功)。

通知即将到来的Bitmap传输,无论是Header还是单个Integer。让不同步是非常容易的。

除非您想深入研究网络同步和流量控制,否则我建议在服务器和客户端之间的每个传输中使用单个TransmissionObject (也许另一个反之亦然)

该对象具有潜力来存储必须传输的任何数据。(通过继承)

最后,当把对象放到网络流上时,你可以使用任何一致的 Serializer

Serializer完成同步信息到需要的地方的所有工作(元信息,如长度和最后的内容)


在我的repro项目中,我想出了这个类来保存位图。

作为如何在服务器上使用它的示例:

    public void Send(Bitmap bmp)
    {
        // prepare Bitmap
        BitmapTransmission bt = new BitmapTransmission(bmp);
        // try transmitting the object
        try
        {
            // lock to exclude other Threads of using the stream
            lock (m_objSendLock)
            {
                bt.Send(m_stream);                    
            }
        } 
        catch (BitmapTransmissionException ex) 
        { // will catch any exception thrown in bt.Send(...)
            Debug.Print("BitmapHeaderException: " + ex.Message);
            ///BitmapTransmissionException provides a Property `CloseConnection`
            /// it will inform you whether the Exception is recoverable
        }
    }

其中m_objSendLock是防止网络流并发访问的Object。m_stream是连接到客户端的NetworkStream。Echo是一个日志机制。

客户端可以通过

接收这些传输。
  public void Receive() {
         BitmapTransmission bt = bt.Receive(m_stream);
         // check for exceptions maybe?
         pictureBox1.Image = bt.Bitmap;
  }

其中再次m_stream,它的NetworkStream连接到服务器

如果你想看一下(混乱但工作)的repro项目,请告诉我。