Исходный порт UDP различен для клиента getsocketname () и сервера recv ()

Привет, мой вопрос прост:

Я пытаюсь установить соединение UDP через соединение TCP (поскольку несколько клиентов подключены к серверу через несколько каналов, и я хочу идентифицировать тех же клиентов через основное соединение TCP)

Я сделал это, создав на клиенте сокет TCP и UDP и передав на сервер локальный порт UDP, назначенный операционной системой случайным образом через TCP. (В Windows я получаю порт после sendto () через getsocketname ()).
На сервере я использую этот порт для отправки UDP-пакетов именно этому клиенту.
К сожалению, порт, который мне действительно нужно отправить, отличается от локального порта, который я отправил на сервер.

Например:

Мой клиент получает локальный UDP-порт 56423. Отправляет его на мой сервер через установленное TCP-соединение. Сервер пытается отправить UDP-пакеты на этот порт -> Failed.
Когда я использую стандартный способ получения порта на сервере через recv () на сокете UDP, он сообщает об исходном порте 30299. (Я должен заранее отправить UDP-пакеты для этой информации, но я хочу избежать реализации UDP рукопожатие соединения)

Как это может быть?

Насколько я понимаю, UDP просто имеет порт назначения и порт источника. Так что должно работать, отправляя клиенту локальный порт на сервер.
Могут ли быть прокси-сервисы между ними, использующие альтернативные порты?

Редактировать:
Некоторый код:

На клиенте:
(s32 = int, c8 = char)

if(m_WinSock == INVALID_SOCKET)
return;

struct sockaddr_storage addr;
s32 len = sizeof(sockaddr);

getsockname(m_WinSock, (SOCKADDR*)&addr, &len);
c8 ipstr[INET6_ADDRSTRLEN + 1];
s32 port;
if(addr.ss_family == AF_INET)
{
struct sockaddr_in *s = (struct sockaddr_in *)&addr;
m_uLocalPort = ntohs(s->sin_port);
inet_ntop(AF_INET, &s->sin_addr, ipstr, sizeof ipstr);
}
else
{ // AF_INET6
struct sockaddr_in6 *s = (struct sockaddr_in6 *)&addr;
m_uLocalPort = ntohs(s->sin6_port);
inet_ntop(AF_INET6, &s->sin6_addr, ipstr, sizeof ipstr);
}

m_uLocalPort передается через TCP после этого.

На сервере:

    SOCKADDR_IN address;
ZeroMemory(&address, sizeof(address));
address.sin_addr = addrin;
address.sin_port = htons((u16)remoteport);
address.sin_family = AF_INET;

remoteport — это порт, отправленный клиентом.

Используя этот код на сервере после отправки пакета от клиента:

struct sockaddr_storage addr;
s32 len = sizeof(sockaddr);
s32 bytes = recvfrom(m_WinSock, m_RecvBuffer, NET_MAX_UDP_SIZE, 0, (SOCKADDR*)&addr, &len);
m_RecvAddress = *(struct sockaddr_in *)&addr;

s32 port = ntohs(m_RecvAddress.sin_port);
printf("recv from port %i\n", port);

Я получаю совершенно другой порт.

0

Решение

Это не надежный подход к проблеме. Например, NAT может мешать и переназначать ваш порт или даже локальный IP-адрес, видимый от вашего клиента. Вам также может понадобиться сделать пробивание дырок в UDP.

Правильный путь не предполагает никакой взаимосвязи между tcp и udp — это разные каналы.

РЕДАКТИРОВАТЬ: Например:

  1. клиент connect() к общедоступному TCP-интерфейсу сервера.
  2. Аутентификация
  3. Сервер отправляет код аутентификации (cookie) клиенту.
  4. клиент sendto() общедоступный интерфейс udp сервера, с cookie.
  5. Сервер получает sockaddr от recvfrom(),
  6. Соотношение серверов такое sockaddr на подключение к TCP, используя cookie. При желании проверьте / ограничьте IP-адрес, чтобы предотвратить использование силы быка другими.
  7. То есть теперь у вас есть пара соединений — принятый сокет TCP вместе с sockaddr для связи udp.

PS. Вы можете также захотеть сделать некоторое шифрование на рукопожатии, но это выходит за рамки вопроса.

2

Другие решения


По вопросам рекламы [email protected]