C++ Отверстие для пробивки UDP(RTP)

Я делаю программу голосового чата клиент-сервер (неуправляемый 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 ответ

Решение

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

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

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

Другие вопросы по тегам