2016-04-01 2 views
2

im пытается отправить изображение через tcp, он работает около 50% времени, остальные 50% просто дают мне черное изображение, и если я отправлю 2 в пространстве, как 3 секунды, он сработает , кто-нибудь знает почему? и как я могу исправить этуОтправка изображения через TCP

Клиент:

    while ((i = stream.Read(datalength, 0, 4)) != 0) 
       { 

        byte[] data = new byte[BitConverter.ToInt32(datalength, 0)]; 
        stream.Read(data, 0, data.Length); 
        this.Invoke((MethodInvoker)delegate 
        { 
         try 
         { 
          Image Screenshot = byteArrayToImage(data); 
          pictureBox1.Image = Screenshot; 
         } 
         catch { } 
        }); 
       } 

Это функция, которая преобразует массив байтов изображения

 public Image byteArrayToImage(byte[] byteArrayIn) 
    { 
     MemoryStream ms = new MemoryStream(byteArrayIn); 
     Image returnImage = Image.FromStream(ms); 
     return returnImage; 
    } 

Сервер:

 Bitmap printscreen = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); 
     Graphics graphics = Graphics.FromImage(printscreen as Image); 
     graphics.CopyFromScreen(0, 0, 0, 0, printscreen.Size); 
       byte[] data = imageToByteArray(Image); 
       stream = client.GetStream(); 
       int length = data.Length; 
       byte[] datalength = new byte[4]; 
       datalength = BitConverter.GetBytes(length); 
       stream.Write(datalength, 0, 4); 
       stream.Write(data, 0, data.Length); 

Это функция который преобразует изображение в байтовый массив

 public byte[] imageToByteArray(System.Drawing.Image imageIn) 
    { 
     MemoryStream ms = new MemoryStream(); 
     imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Gif); 
     return ms.ToArray(); 
    } 

ответ

1

Вы должны убедиться, что прочитали весь «пакет». Не уверен, что вы получаете все только потому, что вы его просите. Метод Read() вернет количество прочитанных байтов, сохранит их и зациклирует до тех пор, пока вы не получите нужное количество байтов.

Замените свой текущий Read() с этим:

int bytesReceived = 0; 
while(bytesReceived < data.Length) 
{ 
    bytesReceived += stream.Read(data, bytesReceived, data.Length - bytesReceived); 
} 

Это будет читать, пока все ваше изображение не было получено.

EDIT: Исправлена ​​ошибка с кодом, благодаря Ivan's answer.

+0

Вы хотите просто заменить «stream.Read (data, 0, data.Length)»; с вашим кодом? или "while ((i = stream.Read (datalength, 0, 4))! = 0)"? спасибо за помощь –

+0

@RachelDockter: Замените 'stream.Read (data, 0, data.Length);' yes. Код будет запрашивать столько байтов, сколько ему не хватает, поэтому, если вы, например, получили все, кроме одного байта, он запросит только один байт. –

+0

@RachelDockter: Если это работает, отметьте это как принятый ответ, нажав галочку слева от сообщения. –

0

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

Вы также, по-видимому, игнорируете результат read() и считаете, что он заполняет буфер.

+0

Я заметил, что после того, как я разместил вопрос, я его отредактирую. его немного лучше, я думаю, но некоторые из них все еще возвращаются в черный цвет. кажется, когда я получаю черный снимок экрана, каждый после этого будет черным, пока я не перезапущу программу. –

+0

См. edit. Как только вы выйдете из синхронизации, вы не будете синхронизированы. – EJP

+0

вы могли бы объяснить abit больше о игнорировании результата чтения(), пожалуйста? im havnt был программированием для долгого времени, а сеть - не моя сильная точка –

Смежные вопросы