Подтвердить что ты не робот

Как долго пакет UDP остается в сокете?

Если данные отправляются клиенту, но клиент занят чем-то другим, как долго будут доступны данные для чтения с помощью recvfrom()?

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

(windows - udp)

4b9b3361

Ответ 1

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

Типичный сетевой драйвер сможет буферизовать несколько пакетов без потери.

Ответ 2

Если данные отправляются клиенту, но клиент занят чем-то другим, как долго будут доступны данные для чтения с помощью recvfrom()?

Навсегда, или совсем нет, или пока вы не закроете сокет или не прочитаете столько, сколько один байт.

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

Единая датаграмма UDP относится только к одному или нескольким "фрагментам", которые представляют собой IP-пакеты (далее инкапсулированные в какой-либо протокол "по проводам", но это не имеет значения). Сетевой стек собирает все фрагменты для дейтаграммы. Если контрольная сумма на любом из фрагментов не является хорошей, или любая другая вещь, которая делает сетевой стек недовольным, полная датаграмма отбрасывается, и вы замечаете, даже не ошибку. Вы просто не знаете, что произошло.

Если все идет хорошо, полная датаграмма помещается в буфер приема. Никогда ничего, и никогда больше. Если вы попытаетесь recvfrom позже, это то, что вы получите.

Буфер приема, очевидно, должен быть достаточно большим, чтобы содержать хотя бы одну дейтаграмму максимального размера (65535 байт), но поскольку обычно датаграммы не будут максимальным размером, а скорее чем ниже 1280 байт (или 1500, если хотите), это обычно может содержать довольно много (на большинстве платформ буфер по умолчанию имеет значение около 128-256k и настраивается). Если в буфере осталось недостаточно места, датаграмма отбрасывается, и вы ничего не получаете (ну, вы все равно получаете те, которые уже находятся в буфере). Опять же, вы даже не знаете, что произошло.

Каждый раз, когда вы вызываете recvfrom, полная датаграмма удаляется из буфера (важная деталь!), и вы получаете до количества запрошенных вами байтов. Это означает, что если вы наивно попробуете прочитать несколько байтов, а затем еще несколько байт, это просто не сработает. Первое чтение отбрасывает остальную часть дейтаграммы, а последующие считывают первые байты некоторых будущих датаграмм (и, возможно, блокируют)!

отличается от тем, как работает TCP. Здесь вы можете прочитать несколько байтов и несколько байт снова, и это будет просто работать, потому что сетевой уровень имитирует поток данных. Вы даете дерьмо, как это работает, потому что сетевой стек гарантирует, что он работает.

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

Вероятно, вы хотели сказать "получил", а не "отправили". Отправлять и получать разные буферы, так что это не имеет значения. О получении другого пакета, пока он еще находится в буфере, см. Приведенное выше объяснение. Если буфер может удерживать вторую дейтаграмму, он сохранит его, иначе он будет тихо идти * poof *.
Это не влияет на какие-либо датаграммы, уже находящиеся в буфере.

Ответ 3

Если данные отправляются клиенту, но клиент занят чем-то другим, как долго будут доступны данные для чтения с помощью recvfrom()?

Это зависит от ОС, в Windows я считаю, что по умолчанию для каждого UDP-сокета 8012, это может быть увеличено с помощью setsockopt() Winsock Documentation Так что, пока буфер не заполнен, данные будут оставаться там до тех пор, пока сокет не будет закрыт или не будет прочитан.

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

Если в буфере есть место, они оба сохраняются, если нет, один из них отбрасывается. Я считаю его самым новым, но я не уверен на 100%.