如何打印从的getaddrinfo IP地址() [英] How to print IP address from getaddrinfo()
问题描述
我试图在CentOS 6.4使用套接字用C
以下LIST1是我的code。
我的code命令行获取主机名和发送数据报给服务器成功UDP。
我想知道的是如何打印IP地址的getaddrinfo()
室内用解析 192.168.10.1
格式
当我尝试打印IP地址分段错误发生。
有谁知道如何解决这个问题code?
的#include<&stdio.h中GT;
#包括LT&;&string.h中GT;
#包括LT&;&unistd.h中GT;
#包括LT&; SYS / types.h中>
#包括LT&; SYS / socket.h中>
#包括LT&; netinet / in.h中>
#包括LT&;&netdb.h中GT;
#包括LT&;&errno.h中GT;INT
主(INT ARGC,CHAR *的argv []){
INT袜子;
结构addrinfo中的提示,*资源;
INT N;
INT犯错;
如果(的argc!= 2){
fprintf中(标准错误,用法:%s的DST \\ n,argv的[0]);
返回1;
}
memset的(安培;提示,0,sizeof的(提示));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
ERR =的getaddrinfo(的argv [1],12345,&安培;提示,&安培; RES);
如果(犯错!= 0){
PERROR(的getaddrinfo);
输出(的getaddrinfo%S \\ n字符串错误(错误));
的printf(的getaddrinfo:%S \\ n,gai_strerror(ERR));
返回1;
} 袜子=插座(水库 - > ai_family,水库 - > ai_socktype,0);
如果(袜子℃,){
PERROR(插座);
返回1;
}
{
为const char * ipverstr;
开关(水库 - > ai_family){
案例AF_INET:
ipverstr =的IPv4;
打破;
案例AF_INET6:
ipverstr =IPv6的;
打破;
默认:
ipverstr =未知;
打破;
}
的printf(ipverstr =%S \\ n,ipverstr);
}
N = SENDTO(袜子,HELLO,5,0,水库 - > ai_addr,水库 - > ai_addrlen);
// N = SENDTO(袜子,HELLO,5,0,(结构sockaddr *)地址,的sizeof(地址));
如果(N。1){
PERROR(SENDTO);
{ }
返回1;
}
结构SOCKADDR_IN *地址;
地址=(结构SOCKADDR_IN *)的水库> ai_addr;
的printf(INET_NTOA(in_addr等)罪=%S \\ n,INET_NTOA((struct in_addr,这个)addr-> sin_addr)); 的printf(############完成!! ####### \\ n);
关闭(袜子);
freeaddrinfo(RES);
返回0;
}
在code偏出包括原型的 INET_NTOA()
。
编译器应该告诉你这一点。
不要添加:
的#include< ARPA / inet.h>
然而,code编译仍然是由于对的 INET_NTOA()
假定返回 INT
,而它返回一个的char *
这是一个指针,它在64位系统上为8字节,这是不相同的大小为 INT
通常具有规模的 4
。由于这种不匹配的东西去可怕的错误,并在分段违例告终。
另请注意: INET_NTOA()
是用于仅IPv4地址。从 男人INET_NTOA逐字
(由我斜体字):
在 INET_NTOA()功能,在网络字节顺序鉴于互联网主机地址,转换为字符串中的的IPv4 的点分十进制格式。该字符串返回一个静态分配的缓冲区,随后的调用将
覆盖
块引用>要能都转换(IPv4和IPv6)的二进制地址到
结构sockaddr_XYZ
的char []
使用inet_ntop()
。I’m trying to use socket in C on CentOS 6.4.
Following LIST1 is my code.
My code gets hostname from command line and sends datagram to server with UDP successfully.
What I want to know is how to print IP address that
getaddrinfo()
resolved wiht192.168.10.1
format.When I try to print IP address segmentation error happens.
Does anyone know how to fix this code?
#include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <errno.h> int main(int argc,char *argv[]){ int sock; struct addrinfo hints,*res; int n; int err; if(argc != 2){ fprintf(stderr,"Usage : %s dst \n",argv[0]); return 1; } memset(&hints,0,sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; err = getaddrinfo(argv[1],"12345",&hints,&res); if(err != 0){ perror("getaddrinfo"); printf("getaddrinfo %s\n",strerror(errno)); printf("getaddrinfo : %s \n",gai_strerror(err)); return 1; } sock = socket(res->ai_family,res->ai_socktype,0); if(sock < 0){ perror("socket"); return 1; } { const char *ipverstr; switch (res->ai_family){ case AF_INET: ipverstr = "IPv4"; break; case AF_INET6: ipverstr = "IPv6"; break; default: ipverstr = "unknown"; break; } printf("ipverstr = %s\n ",ipverstr); } n = sendto(sock,"HELLO",5,0,res->ai_addr,res->ai_addrlen); //n = sendto(sock,"HELLO", 5, 0,(struct sockaddr *)addr, sizeof(addr)); if(n<1){ perror("sendto"); { } return 1; } struct sockaddr_in *addr; addr = (struct sockaddr_in *)res->ai_addr; printf("inet_ntoa(in_addr)sin = %s\n",inet_ntoa((struct in_addr)addr->sin_addr)); printf("############ finish !! #######\n"); close(sock); freeaddrinfo(res); return 0; }
解决方案The code misses to include the prototype for
inet_ntoa()
.The compiler should have told you this.
Do add:
#include <arpa/inet.h>
However the code still compiles as due to the missing protoype for
inet_ntoa()
it is assumed to returnint
, whereas it returns achar*
which is a pointer, which on a 64bit system is 8 bytes, which is not the same size asint
which typically has a size of4
. Due to this mismatch things go terribly wrong and end up in a segmentation violation.
Also please note:
inet_ntoa()
is to be used for ipv4 addresses only. Verbatim fromman inet_ntoa
(italics by me):The inet_ntoa() function converts the Internet host address in, given in network byte order, to a string in IPv4 dotted-decimal notation. The string is returned in a statically allocated buffer, which subsequent calls will overwrite
To be able to convert both (IPv4 and IPv6)
struct sockaddr_XYZ
's binary addresses to achar[]
useinet_ntop()
.这篇关于如何打印从的getaddrinfo IP地址()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!