Установка IPv4/IPv6-адреса и порта в структуру хранения sockaddr _

Я переношу приложение IPv4 в AF -независимую кодовую базу (, оно должно работать с IPv4 и IPv6 ). Теперь я использую sockaddr _хранилище везде, где могу, однако теперь мне нужно установить (populate )a sockaddr _хранилище . Но я не знаю, как правильно. Предыдущий код был:

// defined in data_socket.h
struct sockaddr_in laddr;

Теперь есть эта функция, которая устанавливает sin _адрес и sin _порт:

void DataSocket::SetLocalAddr(const char *addr, const int port)
{
    this->laddr.sin_port = htons(port);
    if(addr != NULL)
        this->laddr.sin_addr.s_addr = inet_addr(addr);
    else
        this->laddr.sin_addr.s_addr = inet_addr("0.0.0.0");
}

Как видите, это старый стиль (, использующий IPv4 ).

Теперь мои изменения ниже. Сначала я изменилсяsockaddr_inкsockaddr_storage

// defined in data_socket.h
struct sockaddr_storage laddr;

Затем я изменил приведенный выше код для поддержки IPv4 и IPv6 :

void DataSocket::SetLocalAddr(const char *addr, const int port)
{ 
switch (this->GetAddrFamily(addr)) {
    case AF_INET:
        (struct sockaddr_in *) this->laddr.sin_port = htons(port);
        if(addr != NULL)
            inet_pton(AF_INET, addr, (struct sockaddr_in *) this->laddr.sin_addr);
        else
            inet_pton(AF_INET, "0.0.0.0", (struct sockaddr_in *) this->laddr.sin_addr);
        break;

    case AF_INET6:
        (struct sockaddr_in6 *) this->laddr.sin6_port = htons(port);
        if(addr != NULL)
            inet_pton(AF_INET6, addr, (struct sockaddr_in6 *) this->laddr.sin6_addr);
        else
            inet_pton(AF_INET6, "0:0:0:0:0:0:0:0", (struct sockaddr_in6 *) this->laddr.sin6_addr);
        break;

    default:
        return NULL;

}

. }

Где GetAddrFamily()это:

int DataSocket::GetAddrFamily(const char *addr)
{
    struct addrinfo hints, *res;
    int status, result;

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;

    if ((status = getaddrinfo(addr, 0, &hints, &res)) != 0)
    {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status));
        return false;
    }

    result = res->ai_family; // This might be AF_INET, AF_INET6,etc..
    freeaddrinfo(res); // We're done with res, free it up

    return result;
}

Кажется, мой путь к комплексу. Это правильный способ сделать это?Поскольку я изменил sockaddr _на хранилище sockaddr _, на самом деле я просто хочу решить этот вопрос в обратном порядке:Получение адреса IPV4 из структуры sockaddr

Я пытаюсь найти лучшее решение, например здесь:http://www.kame.net/newsletter/19980604/в нем говорится никогда не использовать inet_ntop()и inet_pton(), однако в некоторых других (, таких как руководство по сети Beej ), говорится, что inet_ntop()и inet_pton()следует использовать для приложений на основе IPv6 .

Является ли мой способ реализации правильным или я должен изменить его?

8
задан Community 23 May 2017 в 11:46
поделиться