2013-11-21 157 views
3

我試圖在CentOS 6.4上使用C中的套接字。如何從getaddrinfo()打印IP地址

以下LIST1是我的代碼。

我的代碼從命令行獲取主機名,併成功向UDP發送數據報。

我想知道的是如何打印IP地址,其中getaddrinfo()的格式爲192.168.10.1

當我嘗試打印IP地址分段錯誤時發生。

有誰知道如何解決這段代碼?

#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; 
} 

回答

4

該代碼未包含原型inet_ntoa()

編譯器應該告訴你這個。

不要添加:

#include <arpa/inet.h> 

但是代碼仍然編譯它被假定爲由於缺少protoype爲inet_ntoa()返回int,而它返回一個char*這是一個指針,它在64位系統上是8個字節,與int的大小不同,其大小通常爲4。由於這種不匹配,事情發生嚴重錯誤,最終導致分段違規。


另請注意:inet_ntoa()只能用於ipv4地址。從man inet_ntoa(由我斜體)逐字:

INET_NTOA()函數是轉換因特網主機,在網絡字節順序給出的IPv4點分十進制地址,爲字符串。該字符串在一個靜態分配的緩衝區,隨後的調用將覆蓋


爲了能夠既(IPv4和IPv6)struct sockaddr_XYZ的二進制地址轉換爲char[]使用inet_ntop()返回。

+0

我增加了它並獲得了IP地址。 – user1345414

2

getaddrinfo()的對應部分是getnameinfo()。這將一個struct sockaddr變成一個字符串。