System.Drawing.ImageFromStream中的System.ArgumentException

时间:2012-11-10 08:07:34

标签: c# sockets bitmap memorystream

好的,所以我看到有多个人遇到过这个问题,我在某种程度上发现了可能导致这个问题的原因,但我无法弄清楚如何解决这个问题。基本上,我正在尝试通过套接字将客户端的屏幕截图发送到服务器。我在客户端应用程序上截取屏幕截图并使用此方法将其转换为字节数组:

// Convert bitmap to byte method
public static byte[] ImageToByte(Bitmap bitmap)
{
    byte[] imageData;
    using (var stream = new MemoryStream())
    {
        bitmap.Save(stream, ImageFormat.Png);
        imageData = stream.ToArray();
        return imageData;
    }
}

然后我将字节数组和字节数组的长度发送到服务器。收到长度后,服务器使用此方法获取实际数据(这是方法的一部分,因为大多数都不相关):

void dataRecieveCallback(IAsyncResult ar)
{
    try
    {
        int rec = sck.EndReceive(ar);

        if (rec <= 0)
        {
            return;
        }

        recieveBuffer.bufStream.Write(recieveBuffer.buffer, 0, rec);
        recieveBuffer.toRecieve -= rec;

        if (recieveBuffer.toRecieve > 0)
        {
            Array.Clear(recieveBuffer.buffer, 0, recieveBuffer.buffer.Length);
            recieveBuffer.bufStream.Position = 0;
            sck.BeginReceive(recieveBuffer.buffer, 0, recieveBuffer.buffer.Length, SocketFlags.None, dataRecieveCallback, null);
            return;
        }

        // Convert all recieved data in memory stream to a byte array
        byte[] finalBuffer = recieveBuffer.bufStream.ToArray();

然后我使用finalBuffer尝试获取图像,但每当我这样做时,使用此方法:

        TypeConverter tc = TypeDescriptor.GetConverter(typeof(Bitmap));
        Bitmap screenShot = (Bitmap)tc.ConvertFrom(finalBuffer);

我总是从System.ArgumentException获得System.Drawing.ImageFromStream:“参数无效”。此代码适用于发送字符串,但每当我尝试发送图像时,它都不起作用。我非常肯定这是套接字代码的一个问题,因为我尝试通过截取屏幕截图,使用相同的方法将其转换为字节数组,然后使用相同的方法将其转换回来,并且它有效。有谁知道我的代码在这里出了什么问题?

以下是缓冲区代码的一部分

struct RecBuffer 
{ 
   public const int BUFFER_SIZE = 1024;
   public byte[] buffer;
   public int toRecieve;
   public MemoryStream bufStream;

   public RecBuffer(int toRec) 
   {
      buffer = new byte[BUFFER_SIZE];
      toRecieve = toRec;
      bufStream = new MemoryStream(toRecieve);
   }
}

我使用了this tutorial中的相当一部分代码。至少对于接收部分。

1 个答案:

答案 0 :(得分:1)

我认为问题在于您的dataRecieveCallback功能。 在那里你将bufStream的位置重置为零:

if (recieveBuffer.toRecieve > 0)
{
  Array.Clear(recieveBuffer.buffer, 0, recieveBuffer.buffer.Length);
  recieveBuffer.bufStream.Position = 0; // <--Here
  sck.BeginReceive(recieveBuffer.buffer, 0, recieveBuffer.buffer.Length, SocketFlags.None, dataRecieveCallback, null);
  return;
}

这意味着您下次会覆盖已接收的字节 系统调用你的回调函数。

所以,只需删除

recieveBuffer.bufStream.Position = 0;

并且您的代码应该可以正常工作。