发信人: cloudsky (晓舟·轩辕明月), 信区: Linux 标 题: 网络socket编程(3)
发信站: 武汉白云黄鹤站 (Mon Feb 8 20:20:21 1999) , 站内信件 8.
#include man getservbyname 获取服务器端口号 cc [ flag ... ] file ... -lnsl [ library ... ] #include struct hostent *gethostbyname(const char *name); struct hostent *gethostbyaddr(const char *addr, int len, int type); struct hostent *gethostbyname_r(const char *name, struct hostent *result, char *buffer, int buflen, int *h_errnop); struct hostent *gethostbyaddr_r(const char *addr, int length, int type, struct hostent *result, char *buffer, int buflen, int *h_errnop); 这些函数用于获取对主机的描述信息,信息来自/etc/nsswitch.conf 中指定的相关文件。 gethostbyaddr()的参数type指定地址族AF_INET,参数addr对应 IP地址,len对应addr所指向的缓冲区大小。后面的例子演示了如 何将点分十进制IP地址转换成addr参数格式。 gethostbyname()、gethostbyaddr()使用了静态数据区, 这些静态数据区会在每次函数调用中都使用到,在多线 程应用中使用这些函数是有问题的。不知道大家对当年 著名的DOS内核重入记忆尤新否,事实上和这里所述是一个意思。 gethostbyname_r()、gethostbyaddr_r()是支持重入的版本。 参数result必须是一个指向struct hostent的指针,该结构所 用内存空间必须是调用者明确分配下来的。若成功,主机描述 信息将返回到这个结构中。参数buffer必须指向由调用者提 供的缓冲空间。buffer用于存放主机数据,返回值struct hostent 中所有的指针均指向存放在buffer中的数据。buffer必须足够大以 致能存放所有可能返回的数据。参数buflen给出buffer的字节大小。 参数h_errnop应该是一个整型指针,发生错误时这里存放了错误信息。 主机描述信息存放在下列结构中,原型定义在 char *h_name; /* canonical name of host */ char **h_aliases; /* alias list */ int h_addrtype; /* host address type */ int h_length; /* length of address */ char **h_addr_list; /* list of addresses */ #define h_addr h_addr_list[0] /* address, for backward compatiblity */ }; 后面的例子演示了如何从h_addr_list得到点分十进制IP地址。 gethostbyname()、gethostbyaddr()函数调用失败则返回NULL 基于不可重入同样的理由,gethostbyname()、gethostbyaddr()返回的 数据在后续另一次调用中如果想继续保存下来,就必须复制出来保存。 注意前面调用了gethostbyname,后面想调用gethostbyaddr,也存在同样的问题, 不只是同名函数前后调用之间存在这个问题。 gethostbyname_r()、gethostbyaddr_r()返回值如果不是NULL,则总是等于调用者提供的参数。 下面是一个简单的演示程序,从一个点分十进制IP地址 得到主机名、主机别名等信息。 /* cc -o hosttest hosttest.c -lnsl */ #include void main (int argc, const char* argv[]) { u_long addr; struct hostent *hp; char **p; if (argc != 2) { (void)printf(\"\\nUsage: %s IP\\n\ exit (1); } /* 把点分十进制IP地址转换成参数格式 */ if ((int)(addr = inet_addr(argv[1])) == -1) { (void) printf(\"\\nIP must be of the form *.*.*.*\\n\"); exit (2); } hp = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET); if (hp == NULL) { (void)printf(\"host information for %s not found\\n\ exit (3); } (void)putchar('\\n'); for (p = hp->h_addr_list; *p != 0; p++) { struct in_addr in; char **q; (void)memcpy(&in.s_addr, *p, sizeof(in.s_addr)); /* 显示如下 */ /* 134.160.22.7 zhuzhou */ (void)printf(\"%s\%s\ for (q = hp->h_aliases; *q != 0; q++) { (void)printf(\" %s\ } (void)putchar('\\n'); } exit (0); } /* end of main */ inet_addr把点分十进制IP地址转换成gethostbyaddr参数格式 inet_ntoa从struct in_addr结构转换得到点分十进制IP地址。 注意这个演示程序用于多线程应用中是危险的。 这里描述的函数的实现使用了动态加载和运行时共享库,所以使用这些函数的程序 无法静态链接。 gethostbyname和gethostbyname_r使用了/etc/netconfig中 inet协议族的内容和/etc/nsswitch.conf中hosts: entry的内容。 gethostbyaddr和gethostbyaddr_r类似。 如果/etc/netconfig中inet协议族在最后一列nametoaddr_libs是-, 则/etc/nsswitch.conf中hosts: entry将被使用, 否则该列指定的nametoaddr库将被使用,/etc/nsswitch.conf被忽略。 所有返回struct hostent的函数一定在h_name域返回一个主机名。 struct in_addr定义在 man gethostname 获取本地主机名 -- 我问飘逝的风:来迟了? 风感慨:是的,他们已经宣战。 我问苏醒的大地:还有希望么? 大地揉了揉眼睛:还有,还有无数代的少年。 我问长空中的英魂:你们相信? 英魂带着笑意离去:相信,希望还在。 ※ 来源:·武汉白云黄鹤站 s1000e.whnet.edu.cn·[FROM: 202.197.32.24] 华中地区网络中心 因篇幅问题不能全部显示,请点此查看更多更全内容