изображение отправлено через udp повреждено - PullRequest
0 голосов
/ 27 февраля 2012

Я пытаюсь реализовать программу передачи изображений UDP в Java. Отправитель разбивает изображение на 1024-байтовые пакеты, где первые 2 байта являются коротким, несущим порядковый номер, а 3-й байт является флагом, указывающим, является ли пакет последним или нет.

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

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

        double DATAGRAM_MAX_SIZE = 1024;
        byte[] recieveData = new byte[(int) DATAGRAM_MAX_SIZE];
        ByteArrayInputStream bais = new ByteArrayInputStream(recieveData);
        DataInputStream dis = new DataInputStream(bais);

        // Loop until all packets received
        byte isLast = 0;
        while(true) {
            receievePacket = new DatagramPacket(recieveData, recieveData.length);
            try {
                receieveSocket.receive(receievePacket);
            } catch (IOException e) {
                System.out.println("Error receieving packet");
                e.printStackTrace();
            }
            Short sequenceNum = dis.readShort();
            isLast = dis.readByte();
            System.out.println(recieveData[0] + " " + recieveData[1] +" " +  recieveData[2]);
            if (!seenSeq.contains(sequenceNum)) {
                seenSeq.add(sequenceNum);
                bos.write(recieveData, 3, (int) DATAGRAM_MAX_SIZE-3);
            }
            dis.reset();
            // Terminate loop if last packet received
            if (isLast == 1) {
                break;
            }
        }

        //  Byte array to hold image data from stream 
        byte[] imageData = bos.toByteArray();

Всякий раз, когда получателю удается получить все пакеты, здесь получается изображение: enter image description here

Ответы [ 2 ]

6 голосов
/ 27 февраля 2012
  1. Если вы подключаетесь к себе, убедитесь, что используете:

    Socket.setReceiveBufferSize
    

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

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

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

  4. Также обратите внимание, что при настройке соединения несколько пакетов могут быть потеряны, если отправитель скажет, что начал миллисекунды до получателя, поэтому получатель долженвсегда быть готовым, прежде чем отправитель начнет что-либо делать.(это происходит даже на локальном хосте, если потоки не синхронизированы строго)

Отправка изображения по UDP не очень хорошая идея.Изображение, текст - это тип данных, которые действительно должны передаваться по TCP - частичная потеря здесь может оказать существенное влияние.VOIP меньше заботится о потере пакетов, особенно с перемежением и сжатием.

2 голосов
/ 27 февраля 2012

UDP не является надежным транспортным протоколом.Если вам нужна надежность, вам нужно реализовать ее самостоятельно или использовать TCP Read UDP здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...