图片不能通过TCP完全发送

时间:2017-01-26 02:44:57

标签: c#

我有一台服务器&客户模式。客户端应该截取屏幕截图,然后将其发送到服务器。我遇到的问题是缺少屏幕截图的一部分。我的意思是,当在Paint或其他应用程序中打开时,屏幕的3/4是黑色的。当我第二次发送屏幕截图命令时,该文件根本没有打开,它已损坏。

这是我的客户端

if (plainText.Contains("screenshot"))
   {
      Bitmap bitmap = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
      Graphics graphics = Graphics.FromImage(bitmap);
      graphics.CopyFromScreen(0, 0, 0, 0, bitmap.Size);
      bitmap.Save("test.bmp");
      writebuffer = File.ReadAllBytes("test.bmp");
      stream.Write(writebuffer, 0, writebuffer.Length);
   }

如您所见,它需要一个屏幕截图,将图像保存到位图文件,然后将字节读入缓冲区并发送它。

这是我的服务器端

foreach (user c in clientList)
        {
            if (c.RemoteIPAddress == currentRow)
            {
                NetworkStream stream = c.clientTCP.GetStream();
                writeBuffer = Encoding.ASCII.GetBytes("screenshot");
                stream.Write(writeBuffer, 0, writeBuffer.Length);

                byte[] readBuffer = new byte[0];
                readBuffer = new byte[c.clientTCP.ReceiveBufferSize];
                int data = stream.Read(readBuffer, 0, readBuffer.Length);

                string x = new Random().Next().ToString();

                FileStream f = new FileStream(new Random().Next() + ".bmp", FileMode.Create, FileAccess.Write);
                f.Write(readBuffer, 0, data);
                f.Close();
                Process.Start(x + ".bmp");

            }
        }

在这里,我发送命令告诉客户端发送屏幕截图,然后接收屏幕,然后将所述屏幕截图写入位图文件。

我似乎无法弄清楚导致此代码中出现上述问题的原因。

2 个答案:

答案 0 :(得分:4)

大卫的“回答”毫无用处。 “hurr muh protocol”。您的代码无法正常工作的原因是因为数据包的最大大小为65535,并且您假设图像不会大于此值 - 即您只读取一个数据包。要读取所有数据包,请使用此循环。

while (stream.DataAvailable)
{
    data = stream.Read(readBuffer, 0, readBuffer.Length);
    f.Write(readBuffer, 0, data);
}

它将检查流中的数据是否可用,并读取它直到没有任何内容。

答案 1 :(得分:0)

  

我似乎无法弄清楚导致此代码中出现上述问题的原因。

那是因为你没有什么比较它。有许多正确的方法来发送图像和许多正确的方式来接收图像。但是如果你想让你的代码工作,发送者和接收者必须就如何发送图像达成一致。这被称为“协议”,应始终记录下来。

如果您有此协议的文档,则会指定发件人如何指示图像的大小。它将指定接收器如何确定何时具有整个图像。然后,您可以检查以确保发送方和接收方都执行协议所说的内容。如果他们这样做,那么协议就会被打破。

当您使用网络连接或文件并且未使用现有协议或格式时,文档您计划在字节级别使用的协议或格式。这样,通过将其行为与协议指定的行为进行比较,可以判断发送方或接收方是否已损坏。

如果没有协议,就没有办法说出谁有过错,因为没有标准的正确行为来比较它们。

不要认为您的协议太简单而无法记录。如果它如此简单,那么记录它应该很简单。如果您认为文档太复杂,那么您就没有正确实施它的祷告。

顺便说一句,可以使用您的发送代码正确的协议。但这很困难。拥有一个接收代码正确的协议是不可能的,因为它实际上没有办法知道它是否包含整个文件。