Всегда ли дейтаграммы принимаются полностью?

Большинство функций приема дейтаграмм, таких как c's recv или read, класс javas DatagramPacket или pythons SocketServer, включают возможность узнать количество полученных данных.

c:

int amount = recv(sock, buf, n, MSG_WAITALL);

Джава:

int amount = datagramSocket.getLength();

питон:

class MyUDPHandler(socketserver.BaseRequestHandler):
    def handle(self):
        amount = len (self.request[0])

Надежны ли они? Или возможно, что принимаются только части сообщения, например, из-за фрагментации пакета или задержки в сети?
Другими словами: когда я отправляю блок данных переменной длины через udp и получаю его на другом конце, эти значения суммы точно равны размеру исходного чанка?

Редактировать:
ninjalj сделал хорошее замечание, и я хочу включить его сюда. Что происходит, когда приемная функция прерывается, например, сигналом? Что происходит, когда два потока одновременно пытаются получить данные из одного и того же сокета?


person XZS    schedule 28.10.2011    source источник
comment
просто к вашему сведению, ваш Java-код имеет серьезную ошибку в написании «Длина»   -  person Necrolis    schedule 28.10.2011


Ответы (2)


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

Изменить, чтобы включить комментарий Уилла, который является наиболее правильным (т. е. технически):

¹Они могут быть фрагментированы на уровне IP, но сетевой стек на стороне получателя либо полностью соберет дейтаграмму и передаст ее процессу прослушивания в том виде, в каком она была отправлена, либо вообще не подтвердит получение каких-либо данных.

person Jon    schedule 28.10.2011
comment
Технически большие пакеты могут быть фрагментированы, но протокол обрабатывает фрагментацию и повторную сборку, и если он не может быть собран полностью, он помечается как потерянный, поэтому пользователь никогда не заметит. - person Will; 28.10.2011
comment
Воля правильная. Стек UDP в ОС заботится о фрагментации, но фрагментация — это задача на уровне IP. Таким образом, это в равной степени относится как к TCP, так и к UDP. При этом доставка UDP-пакетов не гарантируется. Таким образом, любая повторная передача должна быть обработана вашей программой. - person nemith; 28.10.2011
comment
Однако, если ваш буфер для recv() недостаточно велик для хранения пакета, вы получите усеченные данные. - person nos; 28.10.2011

Частичные дейтаграммы разрешены только для UDP Lite.

person Steve-o    schedule 06.11.2011