1

当我尝试连接到网络服务器时,我的“FritzBox”(住宅网关设备)被配置为阻止所有直接连接到 IP 而不是主机名的连接。但是,connect() 函数只允许我使用 IP 地址进行连接。如何使用主机名连接()到服务器(网络浏览器的方式)?

非常感谢。

4

2 回答 2

2

...我的“FritzBox”(住宅网关设备)配置为阻止所有直接连接到 IP 的连接,而不是主机名...

您似乎正试图绕过 Fritzbox 的儿童保护功能的设置。这些设置实际上意味着它只允许在 HTTP-Request 的 Host-header 中具有真实主机名的 HTTP 连接,而不是仅包含 IP 的连接,即它允许http://example.com/但不允许http://10.10.10.10/。有关 Host 标头的示例,请查看 Wikipedia 上的 HTTP 示例请求

于 2015-05-18T10:25:31.180 回答
1

首先,连接总是连接到 IP 地址,而不是主机名。因此,您的网关正在做的事情与您告诉我们的事情不同,它无法区分客户端如何连接到某物。它可以做的是专门检查某些协议,例如在 HTTP 请求中查找 Host: 标头。

但要回答您的问题:您需要使用 DNS 查找主机名并将其转换为 IP 地址。这可以通过getaddrinfo () 函数一次性完成,getaddrinfo() 将以特定于平台的方式执行查找,例如查看主机文件和/或进行 DNS 查找:例如

int clientfd;  
struct addrinfo hints, *servinfo, *p;
int rc;
const char *port = "80";
const char *host = "www.google.com";

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

if ((rc = getaddrinfo(host, port, &hints, &servinfo)) != 0) {
    fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
    exit(1);
}

// getaddrinfo() can map the name to several IP addresses
for(p = servinfo; p != NULL; p = p->ai_next) {
    if ((clientfd= socket(p->ai_family, 
                  p->ai_socktype,p->ai_protocol)) == -1) {
        perror("socket()");
        continue;
    }

    if (connect(clientfd, p->ai_addr, p->ai_addrlen) == -1) {
        close(sockfd);
        continue;
    }

    break; //got a connection
}

if (p == NULL) {
    fprintf(stderr, "connect() failed\n");
    exit(2);
}

freeaddrinfo(servinfo);

//use clientfd
于 2015-05-18T09:09:51.217 回答