博客声明:http://blog.csdn.net/up_seeker/article/details/8887257
最近在学习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;
interr;
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章后面的内容都能用到,去看一下吧!