【问题标题】:How can I obtain the IPv4 address of the client?如何获取客户端的 IPv4 地址?
【发布时间】:2011-01-30 09:23:21
【问题描述】:

我正在为一个简单的工作项目做准备,并试图让自己熟悉 Unix 开发环境中的套接字编程基础知识。在这一点上,我有一些基本的服务器端代码设置来监听来自客户端的传入 TCP 连接请求,在父套接字创建并设置为监听之后......

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

.
. //parent socket creation and listen code omitted for simplicity
.

//wait for connection requests from clients
while(1)
  {
    //Returns the socketID and address of client connecting to socket
    if( ( newfd = accept(sockfd, (struct sockaddr *)&client, &len) ) == -1 ){
      perror("Accept");
      exit(-1);
    }

    if( (rv = recv(newfd, buf, MAXLEN-1, 0 )) == -1) {
      perror("Recv");
      exit(-1);
    }
    struct sockaddr_in *clientAddr = ( struct sockaddr_in *) get_in_addr((struct sockaddr *)&client);
    inet_ntop(client.ss_family, clientAddr, ip, sizeof ip);
    printf("Receive from %s: query type is %s\n", ip, buf);

    if( ( st = send(newfd, msg, strlen(msg), 0)) == -1 ) {
      perror("Send");
      exit(-1);
    }

    //ntohs is used to avoid big-endian and little endian compatibility issues
    printf("Send %d byte to port %d\n", ntohs(clientAddr->sin_port) );

    close(newfd);
  }

}

我在网上找到了get_in_addr函数,放在我的代码最上面,用它来获取连接的客户端的IP地址...

// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
  if (sa->sa_family == AF_INET) {
    return &(((struct sockaddr_in*)sa)->sin_addr);
  }

  return &(((struct sockaddr_in6*)sa)->sin6_addr);
}

但该函数始终返回 IPv6 IP 地址,因为这就是 sa_family 属性设置的内容。

我的问题是,IPv4 IP 地址是否存储在我正在使用的数据中的任何位置,如果是,我该如何访问它?

非常感谢您的所有帮助!

【问题讨论】:

    标签: unix sockets


    【解决方案1】:

    如果您获得的是 IPv6 地址,那么这就是客户端用来连接的地址。 IPv6 和 IPv4 地址之间没有 1-1 的对应关系,IP 地址和客户端设备之间也没有。

    这有点像说您收到了某人的电子邮件,但您无法从他们的电子邮件地址中计算出他们的邮政地址。

    【讨论】:

    • 我认为可能是这样。感谢您的澄清,我真的很感激!
    【解决方案2】:

    请参阅我网站上的 The need for a "getipv4addr" and "getipv6addr" function 文章。它描述了如何获取运行它的计算机的 IPv4 或 IPv6 地址。

    【讨论】:

      【解决方案3】:

      当您在物理上获取 IPv6 地址时,如果客户端使用 IPv4 连接,则该地址将在 IPv4-mapped address format 中。

      您可以通过访问s6_addr 的字节 12、13、14 和 15 来提取地址的 IPv4 部分。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-27
        • 1970-01-01
        • 2017-05-01
        • 2012-03-14
        • 2012-02-16
        • 2017-10-28
        相关资源
        最近更新 更多