Привет мой вопрос прост:UDP Порт источника отличается от клиента getsocketname() и сервера RECV()
Я пытаюсь установить UDP соединение через соединение TCP (Поскольку несколько клиентов, подключенных через несколько каналов на сервер и я хочу идентифицировать тех же клиентов через основное TCP-соединение)
Я сделал это, создав на клиенте TCP и UDP-сокет и передав локальный порт UDP, назначенный оператором ОС через TCP на сервер. (В Windows я получаю порт после sendto() через getsocketname()). На сервере я использую этот порт для отправки UDP-пакетов этому точенному клиенту. К сожалению, порт, который мне действительно нужно отправить, отличается от локального порта, который я отправил на сервер.
Например:
Мой клиент получает локальный UDP порт 56423, назначенный. Отправляет его на мой сервер через установленное соединение TCP. Сервер пытается отправить UDP-пакеты в этот порт -> Сбой. Когда я использую стандартный способ возврата порта на сервер через recv() в соке UDP, он сообщает об исходном порту 30299. (Я должен заранее отправить UDP-пакеты для этой информации, но я хочу избежать реализации UDP-соединение)
Как это может быть?
Насколько я понимаю, UDP имеет только порт назначения и порт источника. Поэтому он должен работать, отправив локальный порт клиента на сервер. Могут ли быть прокси-сервисы между ними, которые используют альтернативные порты?
Edit: Некоторый код:
На клиенте: (s32 = INT, с8 = голец)
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);
Я получаю совершенно другой порт.
* Как вы отправляете и получаете порт UDP? Вы где-то забыли 'htons' /' ntohs'? Является ли порт '30299' (в вашем примере) источником подключения TCP или целевым портом? –
Кроме того, было бы проще, если бы у сервера был фиксированный номер порта, а клиент просто использовал адрес сервера и номер фиксированного порта в 'sendto'? –
Я отправляю порт через установленное TCP-соединение. Сервер имеет фиксированный номер порта (через bind()), на который клиент отправляет. Я использовал htons/ntohs так, как мне кажется. Он изменяет только порядок байтов, но порядок байтов не является проблемой, посмотрите на байты 56423 и 30299, которые они полностью отличаются. На сервере я хочу отправить UDP pakets правильному клиенту. Для этого мне нужен клиентский (случайный) UDP-порт. Порты, безусловно, являются разъемами UDP. В моем диспетчере задач я вижу, что они привязаны к моему приложению как порты прослушивания UDP. – ecreif