Обнаружение переполнения буфера сокета UDP - PullRequest
0 голосов
/ 06 ноября 2011

Я разрабатываю кроссплатформенный инструмент, который захватывает несколько потоков udp с различной скоростью передачи данных. boost :: asio используется для работы в сети. Есть ли способ обнаружить ситуацию, когда буфер udp был переполнен и потеря данных в сокете могла произойти? Единственный способ, которым я сейчас вижу, - это чтение / proc /% pid% / net / udp, но это не применимо для окон, как вы знаете :). Также я хотел бы использовать функции повышения для этого, если это возможно.

Ответы [ 2 ]

2 голосов
/ 06 ноября 2011

Если вам нужна эта возможность, вы должны закодировать ее в протокол, который вы используете.UDP не способен сделать это сам по себе.Например, вы можете поместить порядковый номер в каждую дейтаграмму.Отсутствующие дейтаграммы будут соответствовать отсутствующим порядковым номерам.

1 голос
/ 28 марта 2012

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

Насколько я знаю, нет портативного способа сделать это и ничего напрямую не поддерживается Boost.

Тем не менее, есть несколько платформенных способов сделать это. В Linux это можно сделать, установив опцию сокета SO_RXQ_OVFL, а затем получив ответы с помощью recvmsg (). Это плохо документировано, но вам может помочь http://lists.openwall.net/netdev/2009/10/09/75.

Один из способов избежать этого, в первую очередь, состоит в увеличении приемных буферов (я полагаю, вы уже исследовали это, но включили его для полноты). Опции SO_RCVBUF кажутся достаточно хорошо поддерживаемыми кроссплатформенными. http://pubs.opengroup.org/onlinepubs/7908799/xns/setsockopt.html http://msdn.microsoft.com/en-us/library/windows/hardware/ff570832(v=vs.85).aspx ОС: es устанавливает верхний предел, который может увеличиться администратором. На Linux, I.E. его можно увеличить с помощью /proc/sys/net/core/rmem_max.

Наконец, для вашего приложения один из способов оценить его «нагрузку», который с большими входными буферами может служить для раннего обнаружения перегрузки, - это ввести временную метку до и после асинхронных операций. В псевдо-коде (не Boost :: Async-адаптированный):

work_time = 0
idle_time = 0

b = clock.now()
while running:
  a = clock.now()
  work_time += a-b
  data = wait_for_input()
  b = clock.now()
  idle_time += b-a
  process(data)

Затем каждую секунду или около того вы можете проверять и сбрасывать work_time / (work_time+idle_time). Если он приближается к 1, вы знаете, что у вас возникли проблемы, и вы можете отправить предупреждение или предпринять другие действия.

...