APUE第16章的示例运行16-8

1 篇文章 0 订阅

博客声明: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;
	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章后面的内容都能用到,去看一下吧!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值