在C#中通过TCP套接字传输图像时出现问题

时间:2012-09-14 17:35:59

标签: c# image sockets tcp bitmap

我要做的是将客户端屏幕的图像传输到服务器。 为此,在客户端,我获取屏幕的图像,将其转换为字节数组,并通过TCP套接字将字节数组发送到服务器。 在服务器端,我将字节数组从客户端转换为图像并将其放在pictureBox中。

嗯,结果似乎在客户端很酷,但我在服务器端获得的图片是扭曲的: http://i.stack.imgur.com/wsLNh.png

右边的图片是客户端(保存屏幕并将其发送到服务器), 服务器端在左侧。 正如您在服务器端看到的那样,图片未满。

我正在使用这些代码发送图像,接收图像并进行转换(字节>图像||图像>字节):

private Image getScreen()
{
    Size s = Screen.PrimaryScreen.Bounds.Size;
    Bitmap b = new Bitmap(s.Height, s.Width);
    Graphics g = Graphics.FromImage(b);
    g.CopyFromScreen(0, 0, 0, 0, s);

    return b;
}

private byte[] BmpToBytes(Image bmp)
{
    MemoryStream ms = new MemoryStream();
    bmp.Save(ms, ImageFormat.Jpeg);
    byte[] bmpBytes = ms.GetBuffer();
    bmp.Dispose();
    ms.Close();

    return bmpBytes;
}

private Image BytesToImg(byte[] bmpBytes)
{
    MemoryStream ms = new MemoryStream(bmpBytes);
    Image img = Image.FromStream(ms);
    return img;
}


Client side:
private void SendScreenToServer()
{
    while (true)
    {
        byte[] sendBytes = new byte[12500];
        sendBytes = BmpToBytes(getScreen());
        pictureBox1.Image = getScreen();
        serverStream.Write(sendBytes, 0, sendBytes.Length);
        serverStream.Flush();
    }
}

Server side:
private void GetScreenFromClient()
{
    while (true)
    {
        byte[] bytesFrom = new byte[12500];
        networkStream.Read(bytesFrom, 0, clientSocket.ReceiveBufferSize);

        try
        {
            pictureBox1.Image = BytesToImg(bytesFrom);
        }
        catch { }
    }
}

任何人都知道我做错了什么?或者是否有其他选择通过套接字传输图像?

3 个答案:

答案 0 :(得分:2)

我会盲目猜测,因为您没有向我们展示您用于传输图像的代码。

stream.Read(buffer,start,length)并不保证您将获得length个字节,而是上限不会溢出缓冲区。您应该检查返回值,该值给出读取的字节数。

修改

检查networkStream.Read(bytesFrom, 0, clientSocket.ReceiveBufferSize)返回的内容。它可能不到12500.

您可能还需要在发送图像之前发送图像的大小,以便能够准确地知道要从流中读取多少字节。

答案 1 :(得分:1)

您忘了设计和实施协议。

    networkStream.Read(bytesFrom, 0, clientSocket.ReceiveBufferSize);

这从TCP数据连接接收一堆字节。接下来你需要根据协议处理这些字节。

接收器如何知道它何时收到整个图像?你必须决定如何然后编码。

答案 2 :(得分:0)

如果您每次通过网络传输整个图像,而不是第一次发送整个图像,并且下次只发送上一个和当前图像之间的差异到服务器和服务器端,那将是一个坏主意。你只需在当前图像上应用差异。您可以搜索谷歌以获得良好的逻辑,通过网络发送图像之间的差异,并在服务器端的当前图像上应用差异。感谢