Windows XP上的C#截图

时间:2013-09-12 15:42:40

标签: c# windows sockets windows-xp screenshot

我做了一个简单的程序,它截取屏幕截图,加密到base64并通过Socket连接发送,它在我的笔记本电脑上工作正常(Windows 7),但是当我在其他计算机(Windows XP)上试用它时,它说"参数无效"当我试图将base64文本转换回图像时,这是我的代码:

客户:

public static Image Do_CaptureDesktop()
{
    Rectangle bounds = default(Rectangle);
    System.Drawing.Bitmap screenshot = null;
    Graphics graph = default(Graphics);
    bounds = Screen.PrimaryScreen.Bounds;
    screenshot = new Bitmap(
                     bounds.Width, 
                     bounds.Height, 
                     System.Drawing.Imaging.PixelFormat.Format32bppArgb);
    graph = Graphics.FromImage(screenshot);
    graph.CopyFromScreen(
                     bounds.X, 
                     bounds.Y, 0, 0, 
                     bounds.Size,      
                     CopyPixelOperation.SourceCopy);
    return screenshot;
}
public static string Do_ImageToBase64(Image image,
              System.Drawing.Imaging.ImageFormat format)
{
    using (MemoryStream ms = new MemoryStream())
    {
        // Convert Image to byte[]
        image.Save(ms, format);
        byte[] imageBytes = ms.ToArray();

        // Convert byte[] to Base64 String
        string base64String = Convert.ToBase64String(imageBytes);
        return base64String;
    }
}
public static void Do_prepareImage()
{
    Image screen = Do_CaptureDesktop();
    string base64Screen = Do_ImageToBase64(screen, ImageFormat.Png);
    byte[] Screens = Encoding.Unicode.GetBytes(base64Screen);
    byte[] Header = Encoding.Unicode.GetBytes("S1");
    byte[] Datas = new byte[Screens.Length + Header.Length];
    Header.CopyTo(Datas, 0);
    Screens.CopyTo(Datas, Header.Length);
    Socket.Send(Datas);
}
private static void ConnectToServer()
{
    int attempts = 0;

    while (!_clientSocket.Connected)
    {
        try
        {
            attempts++;
            Console.WriteLine("Connection attempt " + attempts);
            try
            {
                _clientSocket.Connect(IPAddress.Parse("192.168.1.1"), 100);
            }
            catch (SocketException)
            {

             }
        }
        catch (SocketException)
        {
            Console.Clear();
        }
    }
    Console.Clear();
    Console.WriteLine("Connected");

}
static void Main(string[] args)
{
    ConnectToServer();
    Do_prepareImage();
}

服务器:

public static Image Base64ToImage(string base64String)
{
    // Convert Base64 String to byte[]
    byte[] imageBytes = new byte[4];
    try
    {
        imageBytes = Convert.FromBase64String(base64String);
    }
    catch (Exception)
    {
    }
    MemoryStream ms = new MemoryStream(imageBytes, 0,
                                 imageBytes.Length);

    // Convert byte[] to Image
    ms.Write(imageBytes, 0, imageBytes.Length);
    Image image = Image.FromStream(ms, true); //Here is the error
    return image;
}

public static void ParsePacket(string packet)
{
    if (packet.Substring(1,1).Equals("1"))
    {
        string stringImage = packet.Substring(2, packet.Length - 2); 
        //The line above remove the packet name and leave just the base64 text
        try
        {
            Image screen = Base64ToImage(stringImage);
            pictureBox1.Image = screen;
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }


    }

}

我在服务器端有另一个功能,它将收到的数据包发送到" ParsePacket"功能。 编辑:我重复它在Windows 7上工作正常。

2 个答案:

答案 0 :(得分:2)

我认为问题是你忽略了由:

产生的错误
try
{
    imageBytes = Convert.FromBase64String(base64String);
}
catch (Exception)
{
}

因此,当您致电:

Image image = Image.FromStream(ms, true);

你正在解析一个4字节的空数组(为什么你甚至将它初始化为这个?)检查错误。

该方法通常写得非常糟糕,将其更改为此并查看错误的真正含义:

public static Image Base64ToImage(string base64String)
{
    byte[] imageBytes = Convert.FromBase64String(base64String);
    using (MemoryStream ms = new MemoryStream(imageBytes))
    {
        return Image.FromStream(ms, true);
    }
}

答案 1 :(得分:0)

虽然你的服务器中的接收方法没有包含在内,但我认为你遇到了一个我在SO上看过几次的问题: 通过TCP接收数据只能为您提供已发送消息的一部分以及几乎同时发送的多条消息。

正如我在您的客户端代码中看到的,您在客户端和服务器之间的协议中没有任何长度信息或结束标记。您需要某种信息来识别您是收到了完整的信息还是仅收到了一部分信息(甚至是一次收到的两条信息)。

在服务器的receive方法中,您必须将接收的数据存储在缓冲区中,直到您知道(根据您的协议)您已收到完整的消息。您可以处理此消息并将其从缓冲区中删除。

我猜错误消息是应该转换为图像的非完整消息的结果。

该代码适用于本地主机,因为该消息可以通过环回设备发送而不会将其拆分,因此您可以在一个部分中接收它。