-1

我制作了一个简单的程序,它截取屏幕截图,将其加密为 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 上运行良好。

4

2 回答 2

2

我认为问题是您忽略了以下原因产生的错误:

try
{
    imageBytes = Convert.FromBase64String(base64String);
}
catch (Exception)
{
}

因此,当您致电时:

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

您正在解析一个 4 字节的空数组(为什么还要将其初始化为这个?)Hense 错误。

方法一般写的很烂,改成这个看看到底是什么错误:

public static Image Base64ToImage(string base64String)
{
    byte[] imageBytes = Convert.FromBase64String(base64String);
    using (MemoryStream ms = new MemoryStream(imageBytes))
    {
        return Image.FromStream(ms, true);
    }
}
于 2013-09-12T16:13:12.633 回答
0

虽然您在服务器中的接收方法不包括在内,但我认为您遇到了一个我在 SO 上多次看到的问题:通过 TCP 接收数据可以给您发送的消息的一部分以及一起发送的多条消息几乎在同一时间。

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

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

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

该代码在 localhost 上工作,因为消息可以通过环回设备发送而无需拆分,因此您可以在一个部分中接收它。

于 2013-09-13T06:51:13.633 回答