2011-01-08 2 views
2

Я выполняю программу голосовой чат-сервер (неуправляемый C++, win32), в которой клиенты подключаются к серверу с помощью TCP, а функции textchat/chatroom выполняются в TCP, в то время как вся передача аудио передается через отдельный сокет UDP/RTP (с использованием API из JRTPLIB).C++ Отверстие для отверстий UDP (RTP)

Таким образом, IP известен из TCP-соединения, а номер порта разъема RTP может быть отправлен после установления соединения.

Проблема заключается в том, что в TCP только серверу необходимо выполнять переадресацию портов для связи, чтобы работать в обоих направлениях с момента установления соединения, тогда как в UDP вам нужно будет использовать recvfrom() - которому afaik нужно для портов открываться в первую очередь на стороне клиента, что я не хочу (и не нужно, если вы смотрите на любую многопользовательскую игру или VoIP-клиент)

Чтение источников, которые говорят о UDP Hole Punching (например, http://en.wikipedia.org/wiki/UDP_hole_punching) например, они продолжают упоминать о начале обмена udp с сервером. Это то, что вы на самом деле запускаете udp-разговор (в обоих направлениях) с сервером без того, чтобы клиент открывал какие-либо порты? в TCP, как я уже говорил, вам просто нужно подключиться() к серверу, и общение возможно в обоих направлениях.

Кроме того - я знаю, что RTP построен на UDP, но есть ли что-нибудь еще, что я должен знать о перфорации отверстий RTP (опять же, используя JRTPLIB), что отличает его от UDP?

Заранее благодарен!

+1

Я немного запутался - Отверстие UDP Отверстие выполняется для NAT Traversal, то есть когда вам нужно подключить одноранговую связь, и оба одноранговых узла работают в частной сети (или маршрутизаторе). Сервер используется только как способ «совпадения» двух клиентов. Это то, что вы пытаетесь сделать? – zebrabox

+0

Я пытаюсь достичь UDP/RTP-соединения между клиентами, подключенными к серверу, без открытия клиентами каких-либо портов. Как я понимаю, клиенты обмениваются IP/портами с сервером, который затем делится им между клиентами, чтобы они могли напрямую общаться друг с другом. – KaiserJohaan

+0

Что вы подразумеваете под «открытием любых портов»? Там должны быть порты, открытые для общения, это то, что делает дыра дыры udp. – nos

ответ

3

Существует два возможных определения «открытия порта». Один открывает порт с bind() для UDP или listen() для TCP, другой открывает порт в брандмауэре.

Вам нужно открыть порт с вызовом API, чтобы получить что-то, нет никакого способа обойти его, но вы, вероятно, понимаете это, поэтому я думаю, что вы имеете в виду открытие порта в брандмауэре. Но вам не нужно делать это на стороне, которая инициирует общение (клиент). Это касается как TCP, так и UDP, если ваш брандмауэр не настроен в очень параноидальном режиме. Любой разумный брандмауэр разрешил бы ответ от сервера на UDP-порт, если бы какая-то датаграмма, отправленная с этого порта на тот же сервер раньше времени. Вам нужна только дырочная штамповка, если обе стороны находятся за брандмауэрами/маршрутизаторами NAT. Так это делает Skype.

Кроме того, вам даже не нужно беспокоиться о recvfrom() и подобных материалах. Вы можете просто связать() сокет UDP, а затем использовать connect() и recv()/send() или read()/write() точно так же, как и с TCP.

+0

Я вижу, это имеет смысл. Для клиента, подключается() настраивает это соединение или вы действительно должны отправлять() что-то для брандмауэра, чтобы после этого принимать входящие пакеты на этом порту? – KaiserJohaan

+0

@Kaiser, нет, поскольку UDP является протоколом без установления соединения, все вызовы connect() просто устанавливают адрес по умолчанию для отправки или получения, поэтому вам не нужно указывать его каждый раз. Поэтому сначала вы должны отправить(). –

+0

Я вижу. Спасибо, я собираюсь попробовать это! – KaiserJohaan

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