1

サーバーとクライアントで構成されるプログラムを作成しました。サーバーはスクリーンショットのデスクトップを作成し、クライアントはスクリーンショットを受け取り、フォームに表示します。データ転送に問題があります。小さなストリップしか見えません。サーバー上の画像を送信する前に確認しましたが、問題ありません。ただし、クライアントは間違ったイメージを受け取ります。なにが問題ですか?XAML:

<Window x:Class="TestTCP.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="TestTCP" Height="350" Width="525">
<Grid>
    <Image x:Name="img1" Margin="0"/>

</Grid>
</Window>

コード C#:

  public partial class MainWindow : Window
  {
    public MainWindow()
    {
        InitializeComponent();

        Task rec = new Task(WaitClientQuery);
        rec.Start();

        Task tk = new Task(Send);
        tk.Start();
    }

    private void Send()//server part. take screen and send image
    {
        Bitmap temp = CaptureScreen(true);
        MemoryStream ms3 = new MemoryStream();
        BitmapImage image = new BitmapImage();
        byte[] img_byte;
        try
        {
            ((System.Drawing.Bitmap)temp).Save(ms3, System.Drawing.Imaging.ImageFormat.Bmp);
            image.BeginInit();
            ms3.Seek(0, SeekOrigin.Begin);
            image.StreamSource = ms3;
            image.EndInit();

            JpegBitmapEncoder encoder = new JpegBitmapEncoder();
            encoder.Frames.Add(BitmapFrame.Create(image));
            using (MemoryStream ms = new MemoryStream())
            {
                encoder.Save(ms);
                img_byte = ms.ToArray();
            }

            try
            {

                TcpClient client = new TcpClient("192.168.1.64", 4444);
                NetworkStream netstream = client.GetStream();
                netstream.Write(img_byte, 0, img_byte.Length);
                netstream.Close();
                client.Close();
            }
            catch (Exception)
            {

            }
        }
        catch (Exception ee)
        {

        }
    }

    [StructLayout(LayoutKind.Sequential)]
    struct CURSORINFO
    {
        public Int32 cbSize;
        public Int32 flags;
        public IntPtr hCursor;
        public POINTAPI ptScreenPos;
    }

    [StructLayout(LayoutKind.Sequential)]
    struct POINTAPI
    {
        public int x;
        public int y;
    }

    [DllImport("user32.dll")]
    static extern bool GetCursorInfo(out CURSORINFO pci);

    [DllImport("user32.dll")]
    static extern bool DrawIcon(IntPtr hDC, int X, int Y, IntPtr hIcon);

    const Int32 CURSOR_SHOWING = 0x00000001;

    public static Bitmap CaptureScreen(bool CaptureMouse)
    {
        Bitmap result = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
       try
        {
            using (Graphics g = Graphics.FromImage(result))
            {
                g.CopyFromScreen(0, 0, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);

                if (CaptureMouse)
                {
                    CURSORINFO pci;
                    pci.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(typeof(CURSORINFO));

                    if (GetCursorInfo(out pci))
                    {
                        if (pci.flags == CURSOR_SHOWING)
                        {
                            DrawIcon(g.GetHdc(), pci.ptScreenPos.x, pci.ptScreenPos.y, pci.hCursor);
                            g.ReleaseHdc();
                        }
                    }
                }
            }
        }
        catch
        {
            result = null;
        }

        return result;
    }

    void WaitClientQuery()//receive data(client)
    {
        try
        {
            IPAddress ip ;
            IPAddress.TryParse("192.168.1.64", out ip);
            TcpListener listener = new TcpListener(ip, 4444);
            listener.Start(); 
            while (true)
            {
                TcpClient client = listener.AcceptTcpClient();
                Thread thread = new Thread(new ParameterizedThreadStart(ReadMessage));
                thread.IsBackground = true;
                thread.Start(client);
            }
        }
        catch (Exception ex)
        {
        }
    }

    void ReadMessage(object obj)
    {
        try
        {
            TcpClient client = (TcpClient)obj;
            NetworkStream netstream = client.GetStream();
            byte[] arr = new byte[client.ReceiveBufferSize ];
            int len = netstream.Read(arr, 0, client.ReceiveBufferSize);
            if (len > 0)
            {
                try
                {

                    Action act = delegate
                                     {
                                            MemoryStream strmImg = new MemoryStream(arr);
                                            BitmapImage myBitmapImage = new BitmapImage();
                                            myBitmapImage.BeginInit();
                                            myBitmapImage.StreamSource = strmImg;
                                            myBitmapImage.EndInit();
                                            img1.Source = myBitmapImage;
                                     };
                    this.Dispatcher.BeginInvoke(act);

                }
                catch (Exception ex)
                {
                    string message = ex.Message;
                }

            }
            netstream.Close();
            client.Close(); 
        }
        catch (Exception ex)
        {
        }
    }

}

PS 結果、コンパイル後の画面プログラム: クリックして表示

4

2 に答える 2

1

デフォルト値を使用する主な原因client.ReceiveBufferSizeは 8192 バイトであるため、クライアントはサーバーから転送された十分なイメージを受信しません。私のコードでは、クライアントが画像のサイズを正しく受け取るようにしたいので、BinaryWriter画像の長さを転送するために使用します。クライアント側からはBinaryReader、正確なバイト数とイメージのサイズを読み取って帯域幅を節約していました。この助けを願っています

Sendメソッドで:

TcpClient client = new TcpClient("192.168.1.64", 4444);
 using (NetworkStream netstream = client.GetStream())
 {
     using (BinaryWriter bw = new BinaryWriter(netstream))
     {
        bw.Write(img_byte.Length);
        bw.Write(img_byte, 0, img_byte.Length);
     }

     client.Close();
 }

ReadMessage(object obj)

private void ReadMessage(object obj)
    {
        try
        {
            byte[] arr = null;
            TcpClient client = (TcpClient) obj;
            using (NetworkStream netstream = client.GetStream())
            {
                using (BinaryReader br = new BinaryReader(netstream))
                {
                    var arrLen = new byte[4];
                    br.Read(arrLen, 0, 4);
                    int len = BitConverter.ToInt32(arrLen, 0);
                    if (len > 0)
                    {
                        arr = new byte[len];

                        int read = 0;
                        while (read != len)
                        {
                            read += br.Read(arr, read, arr.Length - read);
                        }
                    }
                }
            }

            if (arr != null && arr.Length > 0)
            {
                try
                {

                    Action act = delegate
                        {
                            MemoryStream strmImg = new MemoryStream(arr);
                            BitmapImage myBitmapImage = new BitmapImage();
                            myBitmapImage.BeginInit();
                            myBitmapImage.StreamSource = strmImg;
                            myBitmapImage.EndInit();
                            img1.Source = myBitmapImage;
                        };
                    this.Dispatcher.BeginInvoke(act);

                }
                catch (Exception ex)
                {
                    string message = ex.Message;
                }

            }

            client.Close();
        }
        catch (Exception ex)
        {
        }
    }
于 2013-04-25T15:13:08.437 に答える
1

client.ReceiveBufferSizeクライアント側には間違った情報があると予想されますが、データをループで読み取ることをお勧めします。

if(netstream.CanRead)
{
                byte[] myReadBuffer = new byte[1024];
                int numberOfBytesRead = 0;

                do
        {
                     numberOfBytesRead = netstream.Read(myReadBuffer, 0, myReadBuffer.Length);                              
                }
                while(netstream.DataAvailable);
}

データを List または memorystream に保存します または、サーバーがすべてのデータを送信する前に、サイズを送信するより簡単な方法かもしれません

netstream.Write(img_byte.Length); //does not work with NetworkStream
netstream.Write(img_byte, 0, img_byte.Length);

クライアントは最初にそれを読み取って、適切なバッファーを割り当てることができます。特定のデータ型を送受信するにBinaryWriterは、あなたからビルドすることをお勧めしますNetworkStream

using (BinaryWriter writer = new BinaryWriter(netstream))
于 2013-04-25T11:09:55.997 に答える