Я удивлен отсутствием документации по miniupnp, я думаю, что многие люди используют его, но почти никакой документации вообще, я нашел кусок кода в источнике RakNet, чтобы направлять меня.
Теперь у меня есть концептуальная проблема …
Я разрабатываю приложение, которое подключается к серверу через UDP (сервер должен быть доступным, UDP-порт сервера является конкретным, который открыт, и я могу проверить это с помощью любого средства проверки открытого порта), затем сервер соединяет двух или более клиентов, разговаривающих друг с другом (p2p), поэтому мне нужно обойти NAT в клиенты для этого работают.
У меня уже есть NAT, работающий, и это уже решает много случаев.
Теперь я хочу добавить функциональность UPNP, чтобы решить эту проблему с помощью NAT.
Я использую miniupnpc, и я обрабатываю соединения с Boost.Asio.
struct UPNPDev * devlist = 0;
devlist = upnpDiscover(2000, 0, 0, 0, 0, 0);
if (devlist) {
std::cout << "\nList of UPNP devices found on the network :\n";
struct UPNPDev * device;
for(device = devlist; device; device = device->pNext) {
std::cout << "\ndesc: " << device->descURL << "\n st: " << device->st << "\n";
}
char lanaddr[64]; /* my ip address on the LAN */
struct UPNPUrls urls;
struct IGDdatas data;
if (UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr)) == 1) {
string port = lexical_cast<string>(socket->local_endpoint().port());
int r = UPNP_AddPortMapping(urls.controlURL, data.first.servicetype,
port.c_str(), port.c_str(), lanaddr, 0, "UDP", 0, "0");
if (r != UPNPCOMMAND_SUCCESS) {
std::cout << "\nupnp fail";
}
char intPort[6];
char intClient[16];
char desc[128];
char enabled[128];
char leaseDuration[128];
r = UPNP_GetSpecificPortMappingEntry(urls.controlURL,
data.first.servicetype,
port.c_str(), "UDP", 0,
intClient, intPort,
desc, enabled, leaseDuration);
if (r != UPNPCOMMAND_SUCCESS) {
std::cout << "\nupnp fail";
}else {
std::cout << "\nupnp success on port " << port;
}
}
}
Как видите, я выполняю UPNP после привязки сокета (я связываю его без определенного порта, как это 🙂
asio::udp::socket socket(*this->ioService, asio::udp::endpoint());
У меня вопрос, имеет ли смысл выполнение этого UPNP? Будет ли этот сокет фактически использовать карту портов UPNP, если я выполню UPNP на случайном порте, связанном с сокетом ПОСЛЕ того, как я его свяжу?
Спасибо, парни!
Задача ещё не решена.