[英]Why inet_ntop() and inet_ntoa() gives different result?
I am creating a UDP server-client program. 我正在创建UDP服务器-客户端程序。 Client requests a file and the server sends to client if found. 客户端请求文件,如果找到,服务器将发送给客户端。 Based on Beej's Guide to Networking, 根据Beej的网络指南,
- inet_ntoa() returns the dots-and-numbers string in a static buffer that is overwritten with each call to the function. inet_ntoa()返回静态缓冲区中的点和数字字符串,该字符串在每次调用该函数时都会被覆盖。
- inet_ntop() returns the dst parameter on success, or NULL on failure (and errno is set). inet_ntop()成功返回dst参数,失败则返回NULL(并设置了errno)。
The guide mentions ntoa is deprecated so ntop is recommended since it supports IPv4 and IPv6. 该指南提到不建议使用ntoa,因此建议使用ntop,因为它支持IPv4和IPv6。
On my code I am getting different results when I use function or the other and my understanding is that they should throw the same result. 在我的代码上,使用函数或其他函数会得到不同的结果,我的理解是它们应该抛出相同的结果。 Anything I am missing? 我有什么想念的吗? Any help would be greatly appreciated. 任何帮助将不胜感激。
Code: 码:
//UDP Client
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#define MAXBUFLEN 1024
#define SER_IP "176.180.226.0"
#define SER_PORT "1212"
// Get port, IPv4 or IPv6:
in_port_t get_in_port(struct sockaddr *sa){
if (sa->sa_family == AF_INET) {
return (((struct sockaddr_in*)sa)->sin_port);
}
return (((struct sockaddr_in6*)sa)->sin6_port);
}
int main(int argc, char *argv[]){
int sock, rv, numbytes;
struct addrinfo hints, *servinfo, *p;
char buffer[MAXBUFLEN];
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
rv = getaddrinfo(NULL, SER_PORT, &hints, &servinfo);
if (rv != 0){
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
exit(1);
}
// Printing IP, should provide same result
for(p = servinfo; p != NULL; p = p->ai_next) {
char str1[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &p->ai_addr, str1, INET_ADDRSTRLEN);
printf("ntop:%s\n", str1) ;
printf("inet_ntoa:%s \n", inet_ntoa(((struct sockaddr_in *)p->ai_addr)->sin_addr));
printf("\n");
}
exit(1);
}
Current output: 电流输出:
ntop:64.80.142.0
inet_ntoa:0.0.0.0
ntop:160.80.142.0
inet_ntoa:127.0.0.1
As per the man
page, in the case of AF_INET
the argument src
must point to a struct in_addr
(network byte order). 根据man
页,对于AF_INET
,参数src
必须指向struct in_addr
(网络字节顺序)。
In your struct addrinfo
you have a pointer to struct sockaddr
which is basically 在您的struct addrinfo
您有一个指向struct sockaddr
的指针,该指针基本上是
sa_family_t sa_family;
char sa_data[];
However, struct sockaddr_in
is 但是, struct sockaddr_in
是
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
So, you need to replace 因此,您需要更换
inet_ntop(AF_INET, &p->ai_addr, str1, INET_ADDRSTRLEN);
by either 由任一
inet_ntop(AF_INET, &p->ai_addr->sa_data[2], str1, INET_ADDRSTRLEN);
(the src
argument may be &p->ai_addr->sa_data[1 << 1]
to avoid the "magic number" 2
- the offset which counts for the port number storage) ( src
参数可以是&p->ai_addr->sa_data[1 << 1]
以避免“幻数” 2
用于计算端口号存储的偏移量)
or 要么
inet_ntop(AF_INET, &((struct sockaddr_in *)p->ai_addr)->sin_addr, str1, INET_ADDRSTRLEN);
Then it will produce correct output. 然后它将产生正确的输出。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.