【问题标题】:c# Send/Recieve Image from Streamc# 从流中发送/接收图像
【发布时间】:2021-07-10 19:26:21
【问题描述】:

我目前编写了以下代码。 客户端服务器端。 我想按需发送图像从服务器到客户端。图片将是来自服务器的截图,所以我的大小总是不同的。

发送第一张图片是一项圆满完成的任务。但是当我发送下一个时,图片框不会刷新。 通过调试我可以看到从服务器到客户端的字节成功通过。但是代码似乎只接收字节而不继续其余代码

“while”循环(客户端)的“注释”行似乎在调试中起作用,但我看不到结果,因为 程序卡在 while 循环中 我无法获得应用程序的前台窗口

我目前正在 Windows 中进行测试,但客户端将进行调整以在 android 上工作

服务器图片 客户图片

服务器

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    Socket client;
    private void button2_Click(object sender, EventArgs e)
    {
        Bitmap bmp = TakingScreenshotEx1();
        bmp.Save("1.jpeg", ImageFormat.Jpeg);

        byte[] buffer = ReadImageFile("1.jpeg");
        int v = client.Send(buffer, buffer.Length, SocketFlags.None);
        Console.WriteLine("Image SENT!");
    }

    private Bitmap TakingScreenshotEx1()
    {
        //Create a new bitmap.
        var bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
                                       Screen.PrimaryScreen.Bounds.Height,
                                       PixelFormat.Format32bppArgb);

        // Create a graphics object from the bitmap.
        var g = Graphics.FromImage(bmpScreenshot);

        // Take the screenshot from the upper left corner to the right bottom corner.
        g.CopyFromScreen(Screen.PrimaryScreen.Bounds.X,
                         Screen.PrimaryScreen.Bounds.Y,
                         0,
                         0,
                         Screen.PrimaryScreen.Bounds.Size,
                         CopyPixelOperation.SourceCopy);

        return bmpScreenshot;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        IPEndPoint iep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9999);
        Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        server.Bind(iep);
        server.Listen(100);
        Console.WriteLine("Waiting for client....");
        client = server.Accept();
    }
    private static byte[] ReadImageFile(String img)
    {
        FileInfo fileinfo = new FileInfo(img);
        byte[] buf = new byte[fileinfo.Length];
        FileStream fs = new FileStream(img, FileMode.Open, FileAccess.Read);
        fs.Read(buf, 0, buf.Length);
        fs.Close();

        GC.ReRegisterForFinalize(fileinfo);
        GC.ReRegisterForFinalize(fs);
        return buf;
    }
}

客户

public Form1()
{
    InitializeComponent();
    pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
}
IPEndPoint iep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9999);
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
byte[] buffer = new byte[1000000];
private void button1_Click(object sender, EventArgs e)
{  

   if(client.Connected != true)
    client.Connect(iep);


 //   while (true)
 //   {
        int v = client.Receive(buffer, buffer.Length, SocketFlags.None);

        Console.WriteLine("Data Received!");

        Stream stream = new MemoryStream(buffer);
        var img = Bitmap.FromStream(stream);
        pictureBox1.Image = img;

 //   }

}

【问题讨论】:

  • 首先,为了让事情变得更容易,你应该使用TcpClientTcpServer。其次,套接字 I/O 与文件 I/O 完全不同。仅仅因为你打电话给Receive 并不意味着你会得到整个数据包。服务器应该先发送数据的长度,然后发送实际数据。然后客户端将读取长度。那时它将从套接字读取,直到它具有所述数据的长度。这通常在循环中完成。
  • 不清楚你在这里问什么。您已注释掉 似乎 有问题的部分,因此您的代码当然不会重现您所询问的问题。如果您取消注释 while (true),那么您将阻止 UI 线程,这是一个在此站点上仅被讨论过数千次的主题。你研究过吗?您应该异步读取数据。此外,虽然Bitmap.FromStream() 可以准确确定它需要读取的字节数可能,但如果它偏离了一个字节,您的客户端将结束同步 ...
  • ... 正在发送数据。我不同意TcpClientTcpServer 一定更好,但绝对必须注意前面评论中的其他信息;您的数据格式必须包含某种机制,以允许接收端点知道单个数据单元(例如图像)的开始和结束位置。
  • TcpClient 和 TcpServer 很棒,但它们不符合我的目标,因为它们无法在 android 中很好地处理。我发送的图像字节,它们都在接收时被读取。 @PeterDuniho 这听起来很有趣,但我不知道如何实现它。我将检查如何解决被阻止的 UI 并返回回复。我可以用什么代替Bitmap.FromStream()

标签: c# image winforms sockets stream


【解决方案1】:

正如Peter Duniho 指出的那样,while loop 阻塞了 UI 线程

我在这里找到了合适的解决方案 How to wait for thread to complete without blocking UI

您还可以检查 Invoking the Main Thread inside Timer Method

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-02
    • 2019-08-03
    • 2019-01-26
    • 2011-02-27
    • 2015-08-16
    • 2010-10-19
    相关资源
    最近更新 更多