APUE第16章的示例執行16-8
阿新 • • 發佈:2019-02-01
最近在學習APUE第十六章的時候老是在執行的關口卡住,現將自己或別人的解決辦法拿出來共享,有更好辦法的希望拿出來和大家晒晒………
APUE的16-8.c是將命令列給出的主機名和服務中的資訊通過getaddrinfo對映到IP地址和埠,並打印出一些主機名、協議型別、埠資訊等
程式碼:
#include "apue.h" //注意,這個標頭檔案是APUE前面講到的一些常用的函式,在此沒有給出,所以不能直接執行! #include <netdb.h> #include <arpa/inet.h> #if defined(BSD) || defined(MACOS) #include <sys/socket.h> #include <netinet/in.h> #endif void print_family(struct addrinfo *aip) { printf(" family: "); switch(aip->ai_family) { case AF_INET: printf("inet"); break; case AF_INET6:printf("inet6"); break; case AF_UNIX: printf("unix"); break; case AF_UNSPEC:printf("unspecified");break; default: printf("unknown"); } return; } void print_type(struct addrinfo *aip) { printf(" type: "); switch(aip->ai_socktype) { case SOCK_STREAM: printf("stream"); break; case SOCK_DGRAM: printf("datagram"); break; case SOCK_SEQPACKET: printf("seqpacket");break; case SOCK_RAW: printf("ram"); break; default: printf("unknown(%d)\n", aip->ai_socktype); } return; } void print_protocol(struct addrinfo *aip) { printf(" protocol: "); switch(aip->ai_protocol) { case 0: printf("default"); break; case IPPROTO_TCP: printf("tcp"); break; case IPPROTO_UDP: printf("udp"); break; case IPPROTO_RAW: printf("raw"); break; default: printf("unknow(%d)", aip->ai_protocol); } return; } void print_flags(struct addrinfo *aip) { printf(" flag: "); if (aip->ai_flags == 0) { printf(" 0"); } else { if (aip->ai_flags & AI_PASSIVE) printf(" passive "); if (aip->ai_flags & AI_CANONNAME) printf(" canonname "); if (aip->ai_flags & AI_NUMERICHOST) printf(" numerichost "); #if defined(AI_NUMERICSERV) if (aip->ai_flags & AI_NUMERICSERV) printf(" numricserv "); #endif #if defined(AI_V4MAPPED) if (aip->ai_flags & AI_V4MAPPED) printf(" v4mapped "); #endif #if defined(AI_ALL) if (aip->ai_flags & AI_ALL) printf(" all "); #endif } return; } //if you want test this program, please type "./a.out IP_addr service_name", for example, ./a.out 192.168.1.1 nfs int main(int argc, char *argv[]) { struct addrinfo *aip, *ailist; struct addrinfo hint; struct sockaddr_in *sinp; const char *addr; int err; char abuf[INET_ADDRSTRLEN]; if (argc != 3) err_quit("Usage:%s nodename service.", argv[0]); hint.ai_flags = AI_CANONNAME; hint.ai_family = 0; hint.ai_socktype = 0; hint.ai_protocol = 0; hint.ai_addrlen = 0; hint.ai_canonname = NULL; hint.ai_addr = NULL; hint.ai_next = NULL; if ((err = getaddrinfo(argv[1], argv[2], &hint, &ailist)) != 0) //你傳入的引數都派上了用場 err_quit("getaddrinfo error:%s", gai_strerror(err)); for (aip = ailist; aip != NULL; aip = aip->ai_next) { print_flags(aip); print_family(aip); print_type(aip); print_protocol(aip); printf("\n\thost: %s ", aip->ai_canonname ? aip->ai_canonname : "-"); if (aip->ai_family == AF_INET) { sinp = (struct sockaddr_in *)aip->ai_addr; addr = inet_ntop(AF_INET, &sinp->sin_addr, abuf, INET_ADDRSTRLEN); printf(" address: %s ", addr ? addr:"unknown"); printf(" port: %d", ntohs(sinp->sin_port)); } printf("\n"); } exit(0); }
APUE上給出的執行方式為:./a.out harry nfs
在執行時如果完全按照APUE上的可能得不到結果,因為你要確保你的linux/Unix上有harry這個使用者/主機,,其實就是給出相應的地址,所以我在執行時搗鼓了半天準備放棄,最後靈光了一下,用如下辦法得出結果:./a.out 127.0.0.1 nfs注:127.0.0.1是迴環測試地址
另外,你可以通過檢視/etc/hosts中的內容,會看到有IP和名字對應的資訊(我的前兩行分別是localhost和Uuntu及其對應的IP),你可以用裡面有的IP或名字來使用,包括APUE的16章後面的內容都能用到,去看一下吧!