С # отправка изображения через сокет

У меня проблема с отправкой скриншота через сокеты в C #.

Клиент:

 private void btnCaptureScreen_Click(object sender, EventArgs e)
    {
        clientSocket = new TcpClient();
        clientSocket.Connect(txtIP.Text, 8888);

        NetworkStream serverStream = clientSocket.GetStream();

        byte[] inStream = new byte[9999999];
        serverStream.Read(inStream, 0, (int)clientSocket.ReceiveBufferSize);
        ImageConverter ic = new ImageConverter();
        Image img = (Image)ic.ConvertFrom(inStream);
        Bitmap bit = new Bitmap(img);
        bit.Save(@"C:\temp\capturas\scn" + numCapturas + ".png", ImageFormat.Png);
        clientSocket.Close();
    }

сервер:

    TcpListener serverSocket = new TcpListener(IPAddress.Parse(LocalIPAddress()), 8888);

    TcpClient clientSocket = default(TcpClient);
    serverSocket.Start();
    NetworkStream networkStream = clientSocket.GetStream();
    Bitmap bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width,  Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);
    Graphics gfxScreenshot = Graphics.FromImage(bmpScreenshot);

    gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);

    ImageConverter converter = new ImageConverter();
            Byte[] sendBytes = (byte[])converter.ConvertTo(bmpScreenshot, typeof(byte[]));
    networkStream.Write(sendBytes, 0, sendBytes.Length);
    networkStream.Flush();

это часть моего кода. Если я сохраню снимок экрана на сервере в папку, он работает правильно, но после того, как я отправлю его через сокет клиенту, клиент показывает только половину изображения, другая половина изображения неверна, потому что она вся серая.

Благодарность!

РЕДАКТИРОВАТЬ: теперь я пытался улучшить логику чтения ... но теперь не работает, возникает исключение ArgumentException, когда я пытаюсь сохранить растровое изображение.

Клиент:

clientSocket = новый TcpClient (); clientSocket.Connect (txtIP.Text, 8888);

    NetworkStream serverStream = clientSocket.GetStream();

    byte[] outStream = System.Text.Encoding.ASCII.GetBytes("screenCapture()$");

    serverStream.Write(outStream, 0, outStream.Length);
    serverStream.Flush();

    byte[] bytesFrom = new byte[10025];
    serverStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize);


    String dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom);
    dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"));
    Int64 lengthdata = Convert.ToInt64(dataFromClient);
    byte[] inStream = new byte[lengthdata];

    int recived = 0;
   while (recived != lengthdata)
    {
        recived += serverStream.Read(inStream, 0,(int)clientSocket.ReceiveBufferSize);
    }

    TypeConverter tc = TypeDescriptor.GetConverter(typeof(Bitmap));
    Bitmap screenShot = (Bitmap)tc.ConvertFrom(inStream); //<--- Exception 
    screenShot.Save(@"C:\temp\capturas\scn" + numCapturas + ".png", ImageFormat.Png);
    clientSocket.Close();

Сервер:

private void sendScreenCapture(NetworkStream networkStream)
{
    Bitmap bmpScreenshot = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, PixelFormat.Format32bppArgb);
    Graphics gfxScreenshot = Graphics.FromImage(bmpScreenshot);

    gfxScreenshot.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size, CopyPixelOperation.SourceCopy);

    ImageConverter converter = new ImageConverter();
    byte[] sendBytes = (byte[])converter.ConvertTo(bmpScreenshot, typeof(byte[]));

    byte[] tamañoImagen = System.Text.Encoding.ASCII.GetBytes(sendBytes.Length.ToString() + "$");
    networkStream.Write(tamañoImagen, 0, tamañoImagen.Length);


    networkStream.Write(sendBytes, 0, sendBytes.Length);
    networkStream.Flush();
}

РЕДАКТИРОВАТЬ 2: Ха-ха, наконец, я понял, мне нужно контролировать позицию в байте []:

  int pos = 0;
   while (lengthdata > 0)
   {
     int recived = serverStream.Read(inStream, pos, (int)lengthdata);
     if (recived == 0) break;
     lengthdata -= recived;
     pos+=recived;
   }

person Roomm    schedule 02.04.2013    source источник
comment
Сколько байтов вы отправляете, сколько вы получаете и как принимающая сторона узнает, что она закончила прием?   -  person CodeCaster    schedule 02.04.2013
comment
когда вы говорите, сколько байтов имеет длина byte []? в этом случае сервер отправляет 199403, а клиент получает 8191: S, и я знаю, когда теоретически завершается, потому что форма размораживается.   -  person Roomm    schedule 02.04.2013
comment
Попробуйте использовать класс Socket вместо TcpListener и TcpClient. Это лучше.   -  person th1rdey3    schedule 02.04.2013


Ответы (1)


Вы читаете clientSocket.ReceiveBufferSize байт один раз и останавливаетесь. Предположительно, изображение больше, поэтому вам не хватает его части. Вам понадобится лучшая логика чтения ...

В общем, звучит так, как будто вы пытаетесь самостоятельно реализовать удаленный рабочий стол - подумайте об использовании настоящего удаленного рабочего стола или аналогичных инструментов.

person Jonathan    schedule 02.04.2013