Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unix 如何获取客户端的IPv4地址?_Unix_Sockets - Fatal编程技术网

Unix 如何获取客户端的IPv4地址?

Unix 如何获取客户端的IPv4地址?,unix,sockets,Unix,Sockets,我正在准备一个简单的工作项目,并试图熟悉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

我正在准备一个简单的工作项目,并试图熟悉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地址是否存储在我使用的数据中的任何位置,如果是,我如何访问它


非常感谢您的帮助

如果您获得的是IPv6地址,则客户端将使用该地址进行连接。IPv6和IPv4地址之间没有1-1对应关系,IP地址和客户端设备之间也没有1-1对应关系


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

参见我网站上的文章。它描述了如何获取运行它的计算机的IPv4或IPv6地址。

当您实际获取IPv6地址时,如果客户端与IPv4连接,则该地址将显示在中


您可以通过访问
s6_addr

的字节12、13、14和15来提取地址的IPv4部分,我想可能是这样的。谢谢你的澄清,我真的很感激!