首页
学习
活动
专区
圈层
工具
发布

()
EN

Stack Overflow用户
提问于 2020-03-09 11:46:29
回答 2查看 11.3K关注 0票数 1

有人能帮我弄到google.com的IP吗?

我在这方面找不到任何好的资源。

大多数关于C网络编程的教程都在同一台计算机上创建客户端套接字和服务器套接字。(我不知道在哪种情况下会有意义)

beej.us上的密码都不适合我。

代码语言:javascript
复制
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>

int main(void)
{
    struct addrinfo* res = NULL;
    getaddrinfo("google.com", "443", 0, &res);

    struct addrinfo* i;

    for(i=res; i!=0; res=res->ai_next)
    {
        printf("%s\n", res->ai_addr->sa_data);
    }
}

输出:

代码语言:javascript
复制
�
�
�
���$u
���$u
���$u
���"u
���"u
���"u
��� u
��� u
��� u
���&u
���&u
���&u
Segmentation fault
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-03-09 11:59:52

在这个语句中,i从未在循环体中被修改,而且由于它没有被初始化,它甚至从未进入循环:

代码语言:javascript
复制
for(i=res; i!=0; res=res->ai_next)
{
    printf("%s\n", res->ai_addr->sa_data);
}

另外,您还缺少一些其他的部分。以下步骤是下面链接的完整示例的一部分:

创建以下struct addrinfo实例

代码语言:javascript
复制
struct addrinfo *result = NULL;
struct addrinfo *ptr = NULL;
struct addrinfo hints;

然后初始化Winsock

代码语言:javascript
复制
   // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);

设置hints address info结构

代码语言:javascript
复制
ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;

调用getaddrinfo

代码语言:javascript
复制
dwRetval = getaddrinfo(argv[1], argv[2], &hints, &result);
if ( dwRetval != 0 ){//handle error}

现在,例如,基于上述,您的循环看起来如下:

代码语言:javascript
复制
   for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {//

在完整示例的命令行中输入"www.google.com“0(链接到下面)将类似于以下内容:

这个完整的视窗例子就在这里注意事项:代码中的Bug,即ptr->ai_cannonname可以为空"www.google.com“,因此在调用之前将该行更改为测试:

代码语言:javascript
复制
if(ptr->ai_canonname) printf("\tCanonical name: %s\n", ptr->ai_canonname);

一个完整的Linux 例子就在这里

票数 1
EN

Stack Overflow用户

发布于 2020-03-09 12:54:57

首先,您从不在循环中修改i,因此最终会有一个无限循环。您需要将循环语句更改为:

代码语言:javascript
复制
for(i=res; i!=NULL; i=i->ai_next)

关于输出,ai_addr字段的类型是struct sockaddr *,它是指向泛型套接字地址结构的指针,其sa_data字段只是该地址的数据的二进制blob,而不是可打印的字符串。

要正确打印这些值,需要使用inet_ntop函数。首先,您需要检查ai_addr->sa_family,看看它是IPv4地址还是IPv6地址。然后,您需要将ai_addr转换为IPv4的struct sockaddr_in *或IPv6的struct sockaddr_in6 *,然后分别将sin_addrsin6_addr字段与address家族一起传递给inet_ntop,以将其转换为字符串。

代码语言:javascript
复制
for(i=res; i!=NULL; i=i->ai_next)
{
    char str[INET6_ADDRSTRLEN];
    if (i->ai_addr->sa_family == AF_INET) {
        struct sockaddr_in *p = (struct sockaddr_in *)i->ai_addr;
        printf("%s\n", inet_ntop(AF_INET, &p->sin_addr, str, sizeof(str)));
    } else if (i->ai_addr->sa_family == AF_INET6) {
        struct sockaddr_in6 *p = (struct sockaddr_in6 *)i->ai_addr;
        printf("%s\n", inet_ntop(AF_INET6, &p->sin6_addr, str, sizeof(str)));
    }
}

输出:

代码语言:javascript
复制
172.217.10.238
172.217.10.238
172.217.10.238
2607:f8b0:4006:813::200e
2607:f8b0:4006:813::200e
2607:f8b0:4006:813::200e
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60599932

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档