【问题标题】:How can I obtain the IP address of my server program?如何获取服务器程序的 IP 地址?
【发布时间】:2010-03-22 23:19:24
【问题描述】:

此问题与another question I just posted 有关。我正在为一个简单的工作项目做准备,并试图让自己熟悉 Unix 开发环境中套接字编程的基础知识。在这一点上,我有一些基本的服务器端代码和客户端代码设置来进行通信。目前,我的客户端代码成功连接到服务器代码,服务器代码向它发送了一条测试消息,然后都退出了。完美的!这正是我想要完成的。现在我正在使用用于获取有关两个环境(服务器和客户端)信息的函数。我想获取我的服务器程序的 IP 地址。这是我目前必须执行此操作的代码,但它不起作用...

int sockfd;
unsigned int len;
socklen_t sin_size;
char msg[]="test message";
char buf[MAXLEN];
int st, rv;
struct addrinfo hints, *serverinfo, *p; 
struct sockaddr_storage client;
char s[INET6_ADDRSTRLEN];
char ip[INET6_ADDRSTRLEN];

//zero struct   
memset(&hints,0,sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;

//get the server info
if((rv = getaddrinfo(NULL, SERVERPORT, &hints, &serverinfo ) != 0)){
  perror("getaddrinfo");
  exit(-1);
}

// loop through all the results and bind to the first we can
for( p = serverinfo; p != NULL; p = p->ai_next)
{
  //Setup the socket
  if( (sockfd = socket( p->ai_family, p->ai_socktype, p->ai_protocol )) == -1 )
  {
    perror("socket");
    continue;
  }

  //Associate a socket id with an address to which other processes can connect
  if(bind(sockfd, p->ai_addr, p->ai_addrlen) == -1){
    close(sockfd);
    perror("bind");
    continue;
  }

  break;
}

if( p == NULL ){
  perror("Fail to bind");
}

inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), s, sizeof(s));
printf("Server has TCP Port %s and IP Address %s\n", SERVERPORT, s);

IP 的输出总是空的...

server has TCP Port 22513 and IP Address ::

对我缺少的东西有什么想法吗?

提前感谢您的帮助!这东西一开始真的很复杂。

【问题讨论】:

    标签: c unix sockets


    【解决方案1】:

    您的套接字可能正在侦听所有可用的接口/地址。 “::”是IPv6地址“0:0:0:0:0:0:0:0”的简写,表示地址未指定。

    这可能是因为您从 getaddrinfo() 请求一个 addrinfo 来侦听任何地址和任何支持流的协议,并且带有未指定地址的 IPv6 恰好排在第一位。不过我有点不确定……

    【讨论】:

    • 附带说明,我不知道您现在在哪里阅读,但有关 Berkely 套接字的确切来源是 beejs 教程:beej.us/guide/bgnet 如果您还没有,请查看。
    【解决方案2】:

    您的代码似乎按照所写的方式正常运行,但可能与预期/预期不同。您正在打印的 IP 地址是正确的,因为您绑定到所有可用的接口,因此服务器将能够接受任何网络接口上的传入 TCP 连接。

    您传递给getaddrinfo()hints 结构会产生以下结果:

    • AF_UNSPEC for ai_family 表示调用者应接受任何地址族
    • ai_socktype 的 SOCK_STREAM 指定流套接字类型
    • ai_flags 中包含的 AI_PASSIVE 导致返回的地址适合用于绑定套接字以接受传入连接
      • 由于 nodename 为 NULL,因此套接字地址结构的 IP 地址部分设置为 IPv4 地址的 INADDR_ANY 或 IPv6 地址的 IN6ADDR_ANY_INIT

    由于在 RFC 3484 排序中 IPv6 地址排在 IPv4 地址之前,getaddrinfo() 返回一个未指定的 IPv6 地址(“0:0:0:0:0:0:0:0”)。

    在对inet_ntop() 的调用中,未指定的 IPv6 地址可以简单地表示为“::”。


    如果您正在寻找可以等同于服务器主机名的地址,您可以通过gethostname() 检索机器的主机名并将其用作节点名 致电getaddrinfo()。由于您为 ai_family 指定 AF_UNSPEC,因此 nodename 的有效描述性名称包括主机名。如果您确实指定了一个特定的 IP 地址来代替 INADDR_ANY / IN6ADDR_ANY_INIT,那么套接字将只接受通过该接口的 TCP 连接。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-02-07
      • 2018-02-23
      • 2018-08-03
      • 2013-05-18
      • 2010-09-22
      • 1970-01-01
      • 2020-09-24
      相关资源
      最近更新 更多