-1

スクリーンショットを撮り、それを base64 に暗号化し、ソケット接続経由で送信する簡単なプログラムを作成しました。ラップトップ (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バイトの空の配列を解析しています(なぜこれに初期化したのですか?)エラーが発生しました。

メソッドは一般的にひどく書かれています。これに変更して、エラーが実際に何であるかを確認してください。

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経由でデータを受信すると、送信されたメッセージの一部だけでなく、送信された複数のメッセージが一緒に表示される可能性がありますほぼ同時に。

クライアント コードに見られるように、クライアントとサーバー間のプロトコルには長さ情報やエンド トークンがありません。完全なメッセージを受信したか、その一部だけを受信したか (または 2 つのメッセージを 1 回のバーストで受信したか) を認識するために、何らかの情報が必要です。

サーバーの receive メソッドでは、完全なメッセージを受信したことが (プロトコルに従って) わかるまで、受信したデータをバッファーに格納する必要があります。このメッセージを処理して、バッファから削除できます。

エラーメッセージは、画像に変換する必要がある不完全なメッセージの結果だと思います。

メッセージを分割せずにループバック デバイス経由で送信できるため、メッセージを 1 つの部分で受信できるため、コードはローカルホストで機能します。

于 2013-09-13T06:51:13.633 に答える