Как заставить клиента в UDP открывать порт при отправке с sendto - PullRequest
1 голос
/ 16 декабря 2011

У меня есть простой сервер и клиент в UDP (WinSocks / C ++).

Я отправляю клиент дейтаграммы -> сервер через sendto и отвечаю с сервера клиенту, используя ip и порт, полученный из функции recvfrom.

Я узнал, что:

  1. Каждое sendto от клиента отправляется с другого порта
  2. При попытке ответить с сервера Windows возвращает WSAECONNRESET (что означает, что порт закрыт - http://support.microsoft.com/kb/263823)

Как правильно ответить клиенту с сервера (т.е. принудительно привязать порт на клиенте при отправке с использованием sendto?)

Редактировать: добавление исходного кода:

bool InitClient()
{
    internal->sock = socket(PF_INET, SOCK_DGRAM, 0);
    char8 yes = 1;
    setsockopt(internal->sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int32));
    return internal->sock != -1;
}
void Send(const IpAddress & target, const uint16 port, const char8 * data, int32 size )
{
    sockaddr_in trgt;
    memset(&trgt, 0, sizeof(trgt));
    trgt.sin_family = AF_INET;
    trgt.sin_port = htons(port);
    trgt.sin_addr.s_addr = target.GetRaw();

    if(sendto(internal->sock, (const char8 *)data, size, 0, (PSOCKADDR)&trgt, sizeof(trgt)) == SOCKET_ERROR)
    {
        LOG("Network sending error: %d", WSAGetLastError());
    }
}

1 Ответ

4 голосов
/ 16 декабря 2011

Вызовите функцию «bind», чтобы указать локальный порт для отправки.Пример использования порта 4567 ниже.Обязательно проверьте возвращаемое значение из bind.Call этот код после создания сокета.

sockaddr_in local = {};
local.family = AF_INET;
local.port = htons(4567);
local.addr = INADDR_ANY;

bind(internal->sock,(sockaddr*)&local, sizeof(local));

Если вы связываетесь с нулевым портом вместо 4567, то ОС выберет случайный порт для вас и будет использоватьдля всех последующих отправлять и получать.Вы можете вызвать getsockname, чтобы узнать, какой порт выбран для вас после вызова bind.

...