【问题标题】:Screenshot not transferring fully屏幕截图未完全传输
【发布时间】:2014-06-15 03:14:51
【问题描述】:

我的程序现在正在将屏幕截图从一台计算机发送到另一台计算机,但在接收端,img 的结果如下:

Bitmap bmpScreenShot = new Bitmap(screenWidth, screenHeight);
                  Graphics gfx = Graphics.FromImage((Image)bmpScreenShot);
                  gfx.CopyFromScreen(0, 0, 0, 0, new Size(screenWidth, screenHeight));
                  bmpScreenShot.Save("pic.jpg", ImageFormat.Jpeg);
                  MemoryStream ms = new MemoryStream();
                  bmpScreenShot.Save(ms, ImageFormat.Jpeg);
                  bmpbyte = ms.ToArray();

                  bmpScreenShot.Dispose();
                  ms.Close();
                  ///////////////////////////
                  Send_Text("" + screenHeight);
                  textBox3.Text += ("\r\nSending Hight=" + screenHeight);
                  Send_Text("" + screenWidth);
                  textBox3.Text += ("\r\nSending Width=" + screenWidth);
                  System.Threading.Thread.Sleep(200);
                  Send_Text("" + bmpbyte.Length);
                  textBox3.Text += ("\r\nSending size of:" + bmpbyte.Length);

                  textBox3.Text += "\r\nTransmiting the Screenshot";
                  stm.Write(bmpbyte, 0, bmpbyte.Length);
                  textBox3.Text += "\r\nSent IMG :)";

上面的代码是它的客户端 我发送图片的大小(高度和宽度以及数组长度)并且它正确传输 但正如我所说,服务器无法获得完整的图片

textBox2.Text += "\r\n Getting h";
            byte[] buffer = new byte[320];
            s.Receive(buffer);
            string str = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
            Array.Clear(buffer, 0, buffer.Length);
            int h = int.Parse(str);
            textBox2.Text += "="+h+"\r\n Getting w";
            s.Receive(buffer);
             str = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
             Array.Clear(buffer, 0, buffer.Length);
             int w = int.Parse(str);
            textBox2.Text += "="+w+"\r\n Getting p";
            s.Receive(buffer);
            str = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
            Array.Clear(buffer, 0, buffer.Length);
            int p = int.Parse(str);
            textBox2.Text += "=" + p;
            byte[] asd = new byte[p];
            Bitmap cc = new Bitmap(h, w);


            s.Receive(asd);

            MemoryStream ms = new MemoryStream(asd);

            Image bmp = Image.FromStream(ms);
            bmp.Save("End.jpg", ImageFormat.Jpeg);
            pictureBox1.Image = bmp;

请注意,所有未定义的东西都在代码中的某个地方定义 并且文本框行仅用于用户界面 我正在使用 localhost \local 网络的另一件事,这一切都是 tcp

【问题讨论】:

    标签: c# image file


    【解决方案1】:

    您没有告诉我们如何发送信息(通过网络?串行?TCP?),但从您的代码中我可以看到一件事:

    您确实收到了要等待的实际字节数,但您并没有等待实际的字节数。

    byte[] asd = new byte[p];
    s.Receive(asd);
    

    这确实创建了一个足够大的字节数组来保存所有字节,但s.Receive(asd) 真的接收所有字节吗?


    在您编辑完问题后,让我澄清一件事:TCP 通信可能是碎片化的。仅仅因为您一次发送 4000 个字节并不能保证接收者一次收到 4000 个字节。他可能不会。这就是Receive 方法返回实际接收到的字节数的原因。

    那么你的接收者需要做的是这个(伪代码):

    int totalBytesRead = 0;
    
    do
    {
        int bytesRead = s.Receive(buffer);
        totalBytesRead += bytesRead;
    
        if (bytesRead == 0)
        {
            // Stream was closed - no more bytes
            break;
        }
        else
        {
            // Write bytesRead bytes from buffer to memory stream
        }
    }
    while (totalBytesRead < expectedNumberOfBytes);
    
    if (totalBytesRead < expectedNumberOfBytes)
        throw new Exception("Premature end of transmission");
    

    实际上,再次考虑并查看您的代码,我注意到您实际上正在向接收器发送 JPEG 字节。接收方的未初始化缓冲区极不可能是有效的 JPEG。

    因此,尽管以上所有内容仍然正确,但我现在怀疑接收者实际上是做错事的人。现在看来,将字节保存到内存流中并不能正常工作。

    我从您的代码中看到您正在将图像保存到文件和内存流中。 文件是否包含有效图片?如果不是,您需要查找未正确创建屏幕截图的原因。如果图片有效,您可以尝试另外两种方法:

    1. 从文件中读取 JPEG 字节而不是创建内存流
    2. 不要在将字节发送到客户端之前处理内存流,而是在此之后

    关于 SO 的一些问题表明,在将图像保存到内存流并从流中获取字节时,时间似乎是一个问题。有时它不起作用。

    【讨论】:

    • 这个,弄一会儿,控制你收到的内容是否为0,如果是启动一个定时器,在给定的时间之后如果它一直传递null那么就说明没有别的了接收。
    • 奇怪,发送所有图像似乎没有很好的时间间隔
    • 这不是时间问题,而是数据包碎片的问题。 stackoverflow.com/questions/756765/…
    • Socket 接收缓冲区的默认大小无论如何都是 8192 字节,所以,如果我没记错的话,你不能在一次接收调用中收到更多。
    • 所以我需要以同样的方式发送它? - 所以它将适合 bytesRead
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-05
    • 1970-01-01
    • 2022-08-11
    • 1970-01-01
    • 2017-02-28
    相关资源
    最近更新 更多