2016-02-20 5 views
2

Я хочу создать P2P-сети со следующими характеристиками:TCP или UDP для большого количества соединений?

  • низкая задержка не является действительно важным
  • потери пакетов в порядке
  • узлы будут посылать только небольшое количество данных вокруг
  • там не будет проблем с NAT/брандмауэром, каждый узел имеет открытый порт в своем общедоступном ip
  • каждый узел подключен ко всем другим узлам

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

Итак, мой вопрос: способен ли TCP обрабатывать вышеуказанные требования в сети, например. 1000 узлов без настройки системы? Будет ли UDP лучше подходит для этого случая? Есть ли что-то еще, что было бы разрывом для обоих протоколов?

+0

Это не вопрос программирования. Это вопрос архитектурного дизайна и, возможно, сетевой вопрос. Он * может * быть в теме на программистах или в других местах, но в настоящее время он не входит в сферу действия, определенную нашим справочным центром. –

+1

Рекомендуется сравнить [TCP vs UDP] (http://www.diffen.com/difference/TCP_vs_UDP) для сравнения. Сравните это с вашим списком характеристик и сделайте свой выбор. UDP, скорее всего, будет самым подходящим выбором. –

ответ

2

Если я правильно помню, использование TCP для подключения к 1000 серверам означало бы, что я должен был использовать 1000 портов для обработки этих соединений.

Вы помните неправильно.
Возьмите веб-сервер, который прослушивает порт 80 и может одновременно обрабатывать 1000 соединений одновременно на этом одном порту. Это связано с тем, что соединение определяется кортежем {client-ip,client-port,server-ip,server-port}. И хотя сервер-ip и сервер-порт одинаковы для всех подключений к этому серверу, клиент-ip и клиент-порт не являются. Даже если клиент-ip тот же (то есть клиент), клиент будет выбирать другой порт источника.

... с. 1000 узлов без настройки системы?

Это зависит от системы, так как каждое открытое соединение должно сохранять состояние и, следовательно, нуждается в памяти. Это может быть проблемой для встроенных систем с небольшой памятью.

В любом случае: если ваш протокол просто отправляет небольшие сообщения, и если потеря пакетов, переупорядочение или дублирование приемлемы, чем UDP, это может быть лучшим выбором, потому что накладные расходы (настройка соединения, ACK ..) меньше и меньше Память. Вы также можете использовать один сокет для обмена данными со всеми 1000 узлами, тогда как с TCP вам потребуется отдельный сокет для каждого соединения (сокет не совпадает с портом!). Использование только одного сокета может обеспечить более простой дизайн приложения.

+0

По-прежнему возможно «истощение порта» с TCP. Если у вас есть одно гнездо для прослушивания, вы теоретически ограничены 65535 на удаленный IP-адрес. И, как правило, это намного меньше, чем в Windows, в прошлом это ограничивало ограничение до ~ 5000. В сочетании с плохой обработкой TIME_WAIT в части ОС вы можете легко найти порт, исчерпанный на определенных удаленных IP-адресах. Я видел это на высокопроизводительных передних концах, которые переходят на один бэкэнд. Однако это не должно быть проблемой для приложения P2P, подобного этому вопросу. –

1

Я хочу изменить ответ Штеффен с несколькими точками:

  1. 1000 соединений нет ничего для любого нормального компьютера и операционной системы.
  2. UDP соответствует вашим требованиям. Это может быть проще запрограммировать, поскольку оно ориентировано на сообщения. TCP обеспечивает поток байтов. Вам нужно сложить протокол обмена сообщениями поверх того, что не так просто. Кроме того, вы должны обрабатывать неработающие TCP-соединения, повторно подключаясь.
  3. Порты не хватает. Нет проблем с потреблением 1000 портов.
1

С UDP вы контролировать «состояние соединения», и это в значительной степени лучший способ сделать что-нибудь пиринговой связанные IF у вас есть большое количество узлов или заботиться о пропускной способности, память и нагрузки на процессор. Перемещая весь элемент управления в ваше приложение в отношении «состояния соединения» каждого узла, вы минимизируете количество ресурсов, потраченных впустую, что точно соответствует вашим потребностям.

Вы обойдете слишком много странностей, зависящих от операционной системы, что ограничивает эффективность TCP с большим количеством подключений. Существует размахивание TIME_WAIT и от десятков до сотен специальных настроек ОС, которые нуждаются в настройке для каждого пользователя вашего приложения P2P, если ему нужны эти высокие номера. Тестируемое приложение, которое я разрешил использовать UDP с помощью ack или TCP, показал только 10% -ную разницу в производительности, независимо от операционной системы, использующей UDP. Производительность TCP всегда была ниже, чем лучший UDP, и ее производительность сильно варьировалась более чем на 600% в зависимости от ОС. С помощью настроек вы можете сделать большинство ОС примерно одинаковыми с использованием TCP, но по умолчанию большинство из них неправильно настроены.

Так что, по моему мнению, сложнее создать надежную сеть UDP P2P по сравнению с TCP, но это часто необходимо. Однако я бы посоветовал только проложить маршрут, если бы у вас был опыт работы в сети, поскольку есть много «ошибок», с которыми нужно иметь дело. Есть библиотеки, которые помогают с этим, как Raknet или Enet. Они предоставляют способы сделать надежный UDP, но по-прежнему требуют большего количества сетевых знаний, чтобы знать, как все это объединяется, тогда как с TCP он в основном скрыт от вас.

В сети однорангового узла у вас часто появляются сообщения, такие как NODE PING, что вам может быть безразлично, если каждый из них всегда будет получен, вам просто все равно, если вы недавно его получили. т.е. вы можете отправлять ping каждые 10 секунд и отключать узел после 60 секунд без пинга. Это означало бы, что вам понадобится 6 ping-пакетов в строке, что очень маловероятно, если узел не будет работать. Если вы получили хотя бы один пинг в течение этого 60-секундного периода, то узел все еще активен. Реализация TCP в этом случае будет связана с большей задержкой и пропускной способностью, поскольку она гарантирует, что EACH ping-сообщение пройдет и заблокирует любые другие данные, выходящие до тех пор, пока это не произойдет. И поскольку вы не можете полагаться на TCP, чтобы надежно сказать вам, что соединение мертво, вы вынуждены добавлять аналогичные функции PING для TCP, помимо всего прочего, TCP уже делает дополнительные с вашими пакетами.

Игры также часто имеют данные, которые, если его не получил клиент, не имеет большого значения, потому что в течение нескольких миллисекунд поступает больше пакетов, что приведет к аннулированию любых пропущенных пакетов. т.е. игрок переходит от A к Z в течение 1 секунды, его клиент отправляет каждый пакет, примерно на расстоянии в 40 миллисекунд. ABCDEFG__I__KLMNOPQRSTUVWXYZ. Мы действительно заботимся, если мы пропустим «H и J», так как каждые 40 мс мы получаем обновления? На самом деле это не значит, что в него может входить предсказание, но обычно это не относится к большинству проектов P2P. Если это был TCP вместо UDP, тогда у него были бы повышенные требования к пропускной способности и добавлена ​​латентность для остальных принимаемых пакетов, так как данные будут повторно отправляться до тех пор, пока они не появятся, в дополнение к дополнительной задержке, которую уже добавляет, вызывая все.

По существу, вы можете снизить латентность и сетевые издержки для многих сообщений в одноранговой сети с использованием UDP. Однако всегда будут какие-то сообщения, которые должны быть отправлены надежно, и это требует, чтобы вы в основном реализовали надежный способ получения пакетов на этот узел, аналогичный TCP. И здесь вам необходим определенный уровень знаний, если вы хотите иметь надежную одноранговую сеть. Некоторые вещи, на которые нужно обратить внимание, включают в себя последовательности пакетов с номером, сообщениями ACK и т. Д.

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

Смежные вопросы