Что делать с UDP-пакетами, приходящими по частям

У меня есть приложение Java, которое получает пакеты UDP в цикле:

while (running) {
    try {
        // Block until a packet is received on the port
        byte[] buffer = new byte[1024];
        DatagramPacket receivePacket = new DatagramPacket(buffer, buffer.length);
        serverSocket.receive(receivePacket);
        ByteArrayInputStream byteIn = new ByteArrayInputStream(receivePacket.getData(), 0, receivePacket.getLength());
        DataInputStream dataIn = new DataInputStream(byteIn);

        // Print packet
        String packetString = "";
        while((packetString = dataIn.readLine()) != null) {
            Log.d("WiFi", packetString);
        }

    } catch (IOException ex) {
        Log.d("WiFi", "Problem receiving: " + ex.toString());
    }
}

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

103, -5.84, 5.64, 140.72, #A-=-22.53,-50.18,248.83,  #G-=52.00,-69.00,-18.00,   #M-=-146.66,-155.18,151.06,   2575012
103, -6.51, 5.62, 140.41, #A-=-22.53,-51.20,248.83,  #G-=23.00,44.00,-7.00,   #M-=-146.21,-156.13,151.06,   2575036
103, -7.23, 5.65, 140.09, #A-=-19.46,-49.15,243.71,  #G-=17.00,68.00,-2.00,   #M-=-144.85,-155.18,151.06,   2575063
103, -7.76, 5.60, 139.81, #A-=-17.41,-50.18,240.64,  #G-=17.00,71.00,0.00,   #M-=-143.94,-155.65,153
.47,   2575090
103, -8.51, 5.34, 139.40, #A-=-12.29,-47.10,233.47,  #G-=31.00,-1.00,-5.00,   #M-=-144.85,-154.70,151.87,   2575135
103, -9.20, 4.76, 138.95, #A-=-15.36,-50.18,239.62,  #G-=22.00,30.00,-3.00,   #M-=-146.66,-156.13,151.87,   2575200
103, -9.82, 4.46, 138.61, #A-=-15.36,-47.10,239.62,  #G-=33.00,1.00,-3.00,   #M-=-145.76,-156.13,152.27,   2575266
103, -10.38, 4.07, 138.23, #A-=-14.34,-48.13,235.52,  #G-=30.00,4.00,-7.00,   #M-=-144.85,-155.65,152.27,   2575372
103, -10.90, 3.76, 137.90, #A-=-14.34,-48.13,237.57,  #G-=29.00,19.00,-4.00,   #M-=-145.30,-156.13,151.47,   2575520
103, -11.41, 3.53, 137.44, #A-=-15.36,-48.13,235.52,  #G-=25.00,18.00,-4.00,   #M-=-146.21,-155.18,151.47,   2576917

Как вы можете видеть в строках 4 и 5, последние завершающие символы из 4 были обрезаны, и прибыл новый пакет из оставшихся символов. Из того, что я читал об UDP, все предупреждают, что UDP не гарантирует прибытия пакетов. В моем случае это не проблема; пропущенный пакет слышит, иначе мое приложение не сломается. Тем не менее, я не нашел ничего о пакетах, которые не обязательно приходят как полные. Фактически, я читал, что этого не происходит.

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


person tomsrobots    schedule 21.02.2014    source источник
comment
Поскольку предполагается, что фрагментация IP-уровня в стеке IP-адресов отменяется до того, как вы увидите пакеты, я подозреваю, что сервер отправляет данные двумя пакетами. Лучше всего воспроизвести условие, наблюдая за трафиком с помощью Wireshark, чтобы увидеть, что на самом деле происходит. Здесь достаточно различных движущихся частей (сервер, сеть, ОС, стек TCP / IP и т. Д.), Поэтому вы вряд ли сможете продвинуться дальше, не увидев сетевой трафик на проводе.   -  person Jim Garrison    schedule 21.02.2014
comment
Я скачал WireShark и смотрю на пакеты. Раньше я не использовал WireShark, а сейчас нахожусь в режиме возиться. Кажется, что происходит то, что стандартный пакет составляет около 156 байтов, но иногда он объединяет их в более крупный пакет (я предполагаю, что ОС реализует какой-то буфер? Это происходит при частом трафике) до 492 байтов. . Этот ответ подразумевает, что я достиг предела. Что обычно с этим делают?   -  person tomsrobots    schedule 22.02.2014
comment
Нет, это относится к фрагментации транспортного уровня. На прикладном уровне либо весь пакет прибывает в пункт назначения, либо нет. UDP никогда не объединит несколько исходных датаграмм в один IP-пакет. Вам нужно будет сопоставить трассировки Wireshark для отладки вывода и воссоздать условие, чтобы увидеть, что отправляется. Обратите внимание на флаги фрагментации IP; Wireshark сообщает вам об обнаружении фрагментов.   -  person Jim Garrison    schedule 22.02.2014


Ответы (1)


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

person user207421    schedule 21.02.2014
comment
Покопавшись, выясняется, что микросхема, которую я использовал для отправки UDP-пакетов (WiFly Rn-Xv), автоматически объединяла данные в более крупные пакеты, а затем разделяла их на несколько пакетов, когда более крупный пакет становился большим. Я предполагаю, что это было сделано, чтобы сократить накладные расходы. Я решил свою проблему, добавив специальный символ в начало моей строки и специальный символ в конец моей строки, чтобы я мог проверить, содержит ли пакет полный объем данных. В противном случае я мог бы добавить новый пакет. - person tomsrobots; 23.02.2014