Ошибка отправки пакета TCP - PullRequest
0 голосов
/ 12 января 2012

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

Вот код:

    // This sends.
    private void NewFrameReceived(object sender, NewFrameEventArgs e)
    {
        Bitmap img = (Bitmap)e.Frame.Clone();

        byte[] imgBytes = EncodeToJpeg(img, 25).ToArray();
        if (_tcpOut.Connected)
        {
            NetworkStream ns = _tcpOut.GetStream();
            if (ns.CanWrite)
            {
                System.Threading.Thread.Sleep(500);
                ns.Write(BitConverter.GetBytes(imgBytes.Length), 0, 4);
                ns.Write(imgBytes, 0, imgBytes.Length);
            }
        }
    }

    // This receives.
    private void listeningThread_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
    {
        // start listening for connections
        _tcpIn = new TcpListener(IPAddress.Any, 54321);
        _tcpIn.Start();

        TcpClient _inClient = _tcpIn.AcceptTcpClient();
        while (true)
        {
            NetworkStream ns = _inClient.GetStream();
            if (ns.CanRead && ns.DataAvailable)
            {
                Byte[] imgSizeBytes = new Byte[4];
                ns.Read(imgSizeBytes, 0, 4);
                int imgSize = BitConverter.ToInt32(imgSizeBytes, 0);

                Byte[] imgBytes = new Byte[imgSize];  <-- ERROR, GET CRAZY LARGE VALUE
                ns.Read(imgBytes, 0, imgSize);

                MemoryStream ms = new MemoryStream(imgBytes);
                Image img = Image.FromStream(ms);

                picVideo.Image = img;
            }
        }
    }

Ответы [ 2 ]

3 голосов
/ 12 января 2012

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

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

вам не нужно этого делать, но это облегчает жизнь, вы можете сделать это просто с помощью простого конечного автомата, который знает, как далеко он получил полученное изображение. Но любое несоответствие при отправке изображения (например, 1 дополнительный байт в потоке) может привести к потере синхронизации навсегда.

1 голос
/ 12 января 2012

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

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

total_bytes_read = 0;
while (total_bytes_read != total_bytes_needed)
{
    bytes_left_to_read = total_bytes_needed - total_bytes_read;
    total_bytes_read += read(buffer, total_bytes_read, bytes_left_to_read);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...