Я кодирую сетевое приложение на Android.
Я думаю о наличии единственного порта UDP и Датаграммного сокета, который получает все датаграммы, которые отправляются в него и затем имеют различные очереди обработки для этих сообщений.
Я сомневаюсь, должны ли у меня быть секунда или треть сокет UDP на резервном устройстве. Некоторые сообщения будут очень коротки (приблизительно 100 байтов), но другие должны будут передать файлы.
Мое беспокойство, ядро Android отбросит маленькие сообщения, если это будет слишком занято, обрабатывая большие?
Обновление "Последние вызовы функции sock_queue_rcv_skb () (в sock.h), который ставит пакет UDP в очередь на сокете, получает буфер. Если больше пространства не оставляют на буфере, пакет отбрасывается. Фильтрация также выполняется этой функцией, которая называет sk_filter () точно так же, как TCP сделал. Наконец, data_ready () назван, и пакетный прием UDP завершается".
Давайте сначала разберемся с основами:
Каждый сокет имеет буфер приема и отправки. Когда сетевое оборудование сигнализирует о прибытии нового пакета и , буфер приема заполнен, пакет отбрасывается. Размер буфера контролируется с помощью параметров сокета SO_RCVBUF
и SO_SNDBUF
, см. setsockopt (3)
. ОС устанавливает некоторые значения по умолчанию (и есть файл /etc/sysctl.conf
). Это в системе BSD:
~$ sysctl -a|grep space net.inet.tcp.recvspace=16384 net.inet.tcp.sendspace=16384 net.inet.udp.recvspace=41600 net.inet.udp.sendspace=9216
Разница между TCP и UDP заключается в том, что первый обеспечивает упорядочение данных и повторную передачу отброшенных пакетов, а также управление потоком (медленное читатель замедляет быстрый писатель), а последний - нет.
Так что да, использование UDP для передачи файлов - не лучший , но работоспособный вариант. Просто нужно заново изобрести часть TCP и сопоставить накладные расходы, связанные с этим изобретением, с издержками TCP. С другой стороны, общая мудрость заключается в том, что UDP лучше всего подходит для приложений, которые могут допускать переупорядочение / потерю некоторых пакетов (например, аудио / видеопотоки).
Также существует ошибочное представление о том, что каждому сокету нужен отдельный поток для отправки / получения данных, что далеко от истины. Многие отличные высокопроизводительные сетевые приложения были написаны без потоков, но с использованием неблокирующих сокетов и некоторого механизма опроса (см. select (2)
, poll (2)
, epoll (7)
).
К самому вопросу:
Да, ядро может отбрасывать пакеты, если приложение слишком занято, чтобы сохранить достаточно доступного места в буферах приема сокетов. Но поскольку у каждого сокета свой собственный, поможет разделение потоков управления и данных. Лично я бы пошел на простую настройку TCP-сервера - прослушивание порта, принятие соединения для каждого клиента, реализация значимого протокола поверх потока TCP. Я согласен с тем, что играть с UDP и конечными автоматами протокола низкого уровня - это очень весело, но это уже сделано, и десятилетия исследований ушли на настройку производительности TCP. В конце концов, важны надежность (во-первых) и производительность (во-вторых) вашего приложения.
Надеюсь, это поможет.
UDP - плохая идея для передачи файлов, поскольку вы не можете гарантировать, в каком порядке будут получены пакеты или будут ли они получены вообще. Если вы думаете построить отказоустойчивый транспортный уровень поверх этого, вам следует просто использовать вместо этого TCP / IP, поскольку это именно то, что он делает.
UDP не буферизует полученные пакеты и не ставит их в очередь. Если пакет получен, и вы ждете данных, вы их получите. Если пакет получен, когда ваша программа занята другой обработкой, вы не получите пакет вообще.Поэтому, если вы получаете два «одновременных пакета» (ну, два очень близко друг к другу), есть большая вероятность, что вы можете пропустить один из них, если вы выполняете какую-либо значительную обработку каждого пакета.
Я не понимаю, как открытие дополнительных портов может вам сильно помочь. Если вы заняты обработкой пакета с порта 1, вы пропустите любые пакеты, поступающие на любые другие порты, которые вы наблюдаете, если каждый из них не работает в выделенном потоке. Было бы гораздо лучше быстро скопировать пакет в свой собственный буфер и передать его другому потоку для его обработки, чтобы ваш поток-слушатель мог вернуться к прослушиванию как можно скорее.
Управление потоком TCP поможет вам уменьшить количество отброшенных пакетов. Его отказоустойчивый и гарантирует, что пакеты будут приходить последовательно.