繁体   English   中英

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

[英]TCP sending images client and server

我有一个客户端应用程序和一个服务器应用程序。 客户端应用程序每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;
        }
    }

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

从本质上讲,当我尝试(成功)重现您的问题时,我怀疑您有同步问题。

宣布即将进行的Bitmap传输的是Header还是单个Integer 完全不同步非常容易。

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

该对象有可能存储必须传输的任何数据 (通过继承)

最后,将对象放在网络流上时,可以使用任何一致的 Serializer

Serializer完成将信息同步到所需位置的所有工作(元信息,例如长度,最后还有内容)


那么在我的摄制项目,我想出了这个类来保存位图。

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

    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是防止在网络流上进行并发访问的对象。 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项目,请告诉我们。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM