我正在准备一个简单的工作项目,并且正在尝试熟悉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地址是否存储在我正在使用的数据中的任何位置,如果是,我该如何访问它?
非常感谢您提供所有帮助!
答案 0 :(得分:4)
如果您正在获取IPv6地址,那么这就是客户端用于连接的内容。 IPv6和IPv4地址之间没有1-1对应关系,IP地址和客户端设备之间也没有对应关系。
有点像说你收到了某人发来的电子邮件,但是你在通过电子邮件地址编制邮政地址时遇到了麻烦。
答案 1 :(得分:0)
请参阅我网站上的The need for a "getipv4addr" and "getipv6addr" function文章。它描述了如何获取运行它的计算机的IPv4或IPv6地址。
答案 2 :(得分:0)
当您实际获得IPv6地址时,如果客户端使用IPv4连接,则地址将位于IPv4-mapped address format。
您可以通过访问s6_addr
的字节12,13,14和15来提取地址的IPv4部分。