2013-09-23 5 views
3

Недавно я реализовал поддержку секвенирования пакетов UDP в своем приложении Android (2.3.3 и 4.0.4), которое передает UDP-пакеты между устройствами. Поддержка последовательности в основном принимает любой байт [] и разделяет его на UDP дружественные размеры и отправляет их как UDP-пакеты. Есть заголовок, который я включаю, который помогает с идентификацией последовательности UDP. Прямо сейчас, похоже, что трансляция большого набора данных через него работает. Любые сверстники, слушающие его, могут собрать последовательность штрафа, а затем обработать данные соответствующим образом. (Я транслирую изображение, сделанное с помощью камеры и голосовых клипов)Есть ли в очереди UDP пакеты UDP для DatagramSocket?

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

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

Во-вторых, у меня только 2 устройства в моей изолированной тестовой среде. Они единственные в тестовой сети Wi-Fi.

В-третьих, эти устройства ничего не делают, кроме как тестировать отправку и прием этих UDP-пакетов.

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

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

СЕЙЧАС, что я объяснил все это, отправляет ли очередь Android очередь UDP-пакетов для обрабатывающего сокета?

Я не думаю, что приемник слишком занят, чтобы принимать UDP-пакеты. (они отправляются каждые 2 секунды)

В настоящее время мой сервис запускает Runnable, который в основном выполняет цикл DatagramSocket.receive(), а затем обрабатывает полученный пакет соответственно.

public class MulticastListenerRunnable implements Runnable { 
    ... 
    public void run() { 
     try { 
      multicastServer = new DatagramSocket(port, null); 
      byte[] buffer = new byte[DatagramSession.DATAGRAM_MAX_SIZE]; 
      DatagramPacket packet = null; 
      byte[] data; 

      while(run) { 
       try { 
        packet = new DatagramPacket(buffer, buffer.length); 
        packet.setLength(buffer.length); 
        multicastServer.receive(packet); 
if(packet.getAddress().getHostAddress().equals("127.0.0.1") || packet.getAddress().getHostAddress().equals(ipAddress)) { 
         continue; 
        } 
        Log.d(TAG, "START PACKET RECEIVE!"); 
        processPacket(packet); 
      } 
     } catch (IOException e) { 
      Log.e(TAG, e.getMessage()); 
     } catch (Exception e) {    
      Log.e(TAG, e.getMessage()); 
     } 
    } 
} 

В моих журналах я буквально вижу: (это отрывок из моего журнала, а не от непосредственно на выходе из кода выше клипа)

03-21 01:26:35.453: D/CommService(6446): START PACKET RECEIVE! 
03-21 01:26:35.507: D/CommService(6446): RECEIVED PACKET: 19 of 28 -> 64977(65000 max) 
03-21 01:26:35.515: D/CommService(6446): RECEIVED PACKET: This packet isn't alone. More to come! 
03-21 01:26:35.515: D/CommService(6446): END PACKET RECEIVE! 


03-21 01:26:39.460: D/CommService(6446): START PACKET RECEIVE! 
03-21 01:26:39.468: W/DatagramSession(6446): Warning, this packet's sequence isn't in order, last -> 18, new -> 20 
03-21 01:26:39.476: D/CommService(6446): RECEIVED PACKET: This packet isn't alone. More to come! 
03-21 01:26:39.476: D/CommService(6446): END PACKET RECEIVE! 

Обратите внимание, что пакет 20 отсутствует. Если я посмотрю журналы журналов отправителя, я увижу, что он отправляет все пакеты каждые 2 секунды. Вы можете видеть в временном коде, что пакет 19 получен в 1:26:35, и пакет 21 получен 1:26:39. (4 секунды между ними)

Я как бы растерялся. Есть проблема с проблемой потери пакетов Android и UDP? Получается ли пакетная очередь пакетов Android/Java UDP в течение определенного периода времени, слишком ли занята обработка других пакетов?

Любые предложения, кроме переключения на TCP, будут полезны. Заранее спасибо!

+0

ОК, я вставил wirehark на свой тестовый Wi-Fi и обнаружил, что Android фактически не отправляет пакет UDP в тех случаях, когда они появляются «отброшены». Я буквально отлаживал и регистрировал вызов DatagramSocket.send(), но в Wireshark не появляется UDP-пакет. Значение, в моем последнем тесте, из 8 пакетов, было получено только 6. Пакеты 4 и 6 не были отправлены, хотя DatagramSocket.send() был вызван?!?!? – garlicman

ответ

1

Хорошо, я исправил свою проблему.

Я переключил свой прямой одиночный поток ScheduledExecutorService + Runnable в моем приложении Service на Runnable, который будет запускать новые исполняемые файлы ExecutorService для обработки полученного DatagramPacket.Я предполагаю, что в моем приемнике была небольшая задержка/блокировка ввода/вывода и раздельное разделение на отдельный поток для обработки пакетных данных. Я передал тесты данных размера 1.8MB между устройствами, использующими новый подход.

+1

Я столкнулся с аналогичной проблемой с двумя небольшими UDP-пакетами, отправленными в короткий пакет с Linux-машины на устройство Android через Wi-Fi каждую секунду. Первый UDP-пакет принят OK. Второе, в основном, пропущено. Я думал о реализации этого точного обходного пути (1 поток для получения и один для обработки). Тем не менее, ваш первоначальный вопрос остается без ответа: пакеты UDP, поставленные в очередь Android, перед тем, как быть отправлены в приложение, или же пакеты как-то перезаписываются в буфере приема Android, если приложение не принимает его вовремя? – Tarik

+0

@garlicman вы можете показать пример, как вы достигли этого, у меня такая же проблема, и я застрял. –

+0

@Tarik Я пытался сохранить обработку пакета в отдельном потоке с помощью очереди, но все же есть потеря пакетов, когда два пакета поступают через короткий промежуток времени. Не могли бы вы взглянуть на http://stackoverflow.com/questions/38891610/packet-loss-while-receiving-udp-broadcast-in-android? –

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