С ++ Перфорация отверстий c ++ (RTP) - PullRequest
2 голосов
/ 08 января 2011

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

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

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

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

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

Заранее спасибо!

1 Ответ

3 голосов
/ 08 января 2011

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

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

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

...