在具有 DNS 名称时创建套接字

Create socket when have DNS name

本文关键字:创建 套接字 DNS      更新时间:2023-10-16

Bellow是我用来连接到Windows中的套接字的代码。有时我没有 IP dress,但在 inetAddr 中有 DNS 名称。可能我必须从主机名解析地址,或者可以使用DNS名称创建套接字?当有DNS名称时,创建套接字的最佳方法是什么?

commStatus communicate( const char * tx, char * rx, const int bufSize , const char * inetAddr, const int port )
{
...
        SOCKET s;
        struct sockaddr_in server;

        server.sin_addr.s_addr = inet_addr(inetAddr);
        server.sin_family = AF_INET;
        server.sin_port = htons( port );
        if((s = socket(AF_INET , SOCK_STREAM , 0 )) == INVALID_SOCKET)
        {
            FILELOGL("Could not create socket : " << WSAGetLastError(),Level::Error );
        } else
        {
            if (connect(s , (struct sockaddr *)&server , sizeof(server)) < 0)
            {
                FILELOGL("connect error", Level::Error);
                r= commStatus::COMM_NO_TRANSMIT ;
            } else
            {
            ...
            }
        }
...
}

只有一种方法:解析主机名。

这是我修改但尚未测试的代码的一部分,但它应该可以工作:

WSADATA wsdata;
const char * inetAddr
addrinfo hints, *res;
WSAStartup (MAKEWORD (2, 2), &wsdata);
memset(&hints, 0, sizeof hints);
hints.ai_family     = AF_UNSPEC;
hints.ai_socktype   = SOCK_STREAM;
hints.ai_protocol   = IPPROTO_TCP;
if (getaddrinfo("someaddress.com", NULL, &hints, &res) != 0)
    return false;
inetAddr = inet_ntoa(((sockaddr_in *) res -> ai_addr) -> sin_addr);

您需要解析 DNS 名称。 为此使用getaddrinfo()。 请注意,DNS 名称可以解析为多个 IP,包括 IPv4 和 IPv6,因此您必须首先调用getaddrinfo()以了解报告了多少个 IP,以及为每个 IP 创建哪种类型的套接字。

例如:

commStatus communicate( const char * tx, char * rx, const int bufSize , const char * inetAddr, const int port )
{
    ...
    SOCKET s = INVALID_SOCKET;
    struct addrinfo hint = {0};
    hint.ai_flags = AI_NUMERICHOST;
    hint.ai_family = AF_UNSPEC;
    hint.ai_socktype = SOCK_STREAM;
    hint.ai_protocol = IPPROTO_TCP;
    struct addrinfo *addrs = NULL;
    int ret = getaddrinfo(inetAddr, NULL, &hint, &addrs);
    if (ret == EAI_NONAME)
    {
        hint.ai_flags = 0;
        ret = getaddrinfo(inetAddr, NULL, &hint, &addrs);
    }
    if (ret != 0)
    {
        FILELOGL("Could not resolve inetAddr: " << ret, Level::Error);
    }
    else
    {
        for (struct addrinfo *addr = addrs; addr != NULL; addr = addr->ai_next)
        {
            s = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
            if (s == INVALID_SOCKET)
            {
                FILELOGL("Could not create socket : " << WSAGetLastError(), Level::Error);
                break;
            }
            if (connect(s, addr->ai_addr, addr->ai_addrlen) == 0)
                break;
            closesocket(s);
            s = INVALID_SOCKET;
            if (addr->ai_next == NULL)
            {
                FILELOGL("connect error", Level::Error);
            }
        }
        freeaddrinfo(addrs);
        if (s != INVALID_SOCKET)
        {
            ...
        }
    }
    ...
}