名字和数值地址间进行转换的函数:gethostbyname和gethostbyaddr在主机名字与IPv4地址之间进行转换。getservbyname和getservbyport在服务器名字和端口号之间进行转换。还有两个协议无关的转换函数:getaddrinfo和getnameinfo,分别用于主机名字和IP地址之间以及服务名字和端口之间的转换。

1.gethostbyname函数

通过传入域名或者主机名,返回一个指向hostent结构的指针,该结构中含有所查找主机的所有IPv4地址。这个函数的局限是只能返回IPv4地址。

#include <netdb.h>
struct hostent *gethostbyname(const char *hostname)

本函数返回的非空指针指向如下的hostent结构。

struct hostent {
char *h_name; /* official 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 */
}

h_name为正式主机名

h_aliases为所有的别名

h_addrtype为AF_INET

h_length为4

h_addr_list为IPv4地址

#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <sys/socket.h>
#define MAX 100
int main(int argc, char **argv)
{
char *ptr, **pptr;
char str[MAX];
struct hostent *hptr; while (--argc > 0) {
ptr = *++argv;
if ( (hptr = gethostbyname(ptr)) == NULL) {
printf("gethostbyname error for host: %s: %s",
ptr, hstrerror(h_errno));
continue;
}
printf("official hostname: %s\n", hptr->h_name); for (pptr = hptr->h_aliases; *pptr != NULL; pptr++)
printf("\talias: %s\n", *pptr); switch (hptr->h_addrtype) {
case AF_INET:
pptr = hptr->h_addr_list;
for ( ; *pptr != NULL; pptr++)
printf("\taddress: %s\n",
inet_ntop(hptr->h_addrtype, *pptr, str, sizeof(str)));
break; default:
printf("unknown address type");
break;
}
}
exit(0);
}

运行结果:

huangcheng@ubuntu:~$ ./a.out www.a.shifen.com www.baidu.com
official hostname: www.a.shifen.com
address: 115.239.210.27
address: 115.239.210.26
official hostname: www.a.shifen.com
alias: www.baidu.com
address: 115.239.210.27
address: 115.239.210.26

即百度的正式主机名为: www.a.shifen.com;域名为:www.baidu.com

huangcheng@ubuntu:~$ ./a.out www.hikvision.com
official hostname: www.hikvision.com
address: 223.4.99.235

2.gethostbyaddr函数

gethostbyaddr函数试图由一个二进制的IP地址找到相应的主机名,与gethostbyname的行为刚好相反。

#include <netdb.h>
struct hostent *gethostbyaddr(const char *addr,socklen_t len,int family);

addr参数实际上不是char *类型,而是一个指向存放IPv4地址的某个in_addr结构的指针(注意,这里不是简单的字符串,需要先将字符串形式的IP地址由inet_aton转化一下);len参数是这个结构的大小:对于IPv4地址为4。family参数为AF_INET。

#include<arpa/inet.h>
#include<unistd.h>
#include<netdb.h>
#include<sys/utsname.h>
#include<stdlib.h>
#include<stdio.h> int main()
{
struct hostent *pHost = NULL;
char str[100];
in_addr_t addr = inet_addr("192.168.2.103");
pHost = gethostbyaddr((char*)&addr,4,AF_INET); /* struct utsname Name;
uname(&Name);
pHost = gethostbyname((char*)&Name);*/
printf("official hostname:%s\n",pHost->h_name); char **pAliases = pHost->h_aliases;
for(; NULL != *pAliases; pAliases++)
printf("aliases:%s\n",*pAliases); char **pAddrlist = NULL;
switch(pHost->h_addrtype)
{
case AF_INET:
case AF_INET6:
pAddrlist = pHost->h_addr_list;
for(; NULL != *pAddrlist; pAddrlist++)
printf("address:%s\n",inet_ntop(pHost->h_addrtype,*pAddrlist,str,sizeof(str)));
break;
default:
printf("unknown type\n");
break;
} return 0;
}

运行结果:

huangcheng@ubuntu:~$ ./a.out
official hostname:ubuntu.local
address:192.168.2.103

3.getservbyname函数

像主机一样,服务也通常靠名字来认知。如果我们在程序代码中通过其名字而不是其端口号来指代一个服务,而且从名字到端口号的映射关系保存在一个文件中(通常是/etc/services),那么即使端口号发生变动,我们需需修改的仅仅是/etc/services文件中的某一行,而不必重新编译应用程序。getservbyname函数用于根据给定名字查找相应服务。

#include <netdb.h>
struct serven *getservbyname(const char *servname,const char protoname);

本函数返回的非空指针指向如下的servent结构:

           struct servent {
char *s_name; /* official service name */
char **s_aliases; /* alias list */
int s_port; /* port number */
char *s_proto; /* protocol to use */
}

服务名参数:servname     协议参数:protoname

servent结构中我们关心的主要字段是端口号。既然端口号是以网络字节序返回的,把它存放到套接字地址结构时绝对不能调用htons。

本函数的典型调用如下:

struct serven *sptr;
sptr = getservbyname("domain","udp"); /*DNS using UDP*/
sptr = getservbyname("ftp","tcp"); /*FTP using TCP */
sptr = getservbyname("ftp",NULL); /*FTP using TCP"*/
sptr = getservbyname("ftp","udp"); /*this call will fail*/

既然FTP仅仅支持TCP,第二个调用和第三个调用等效,第四个调用则会失败。

4.getservbyport函数

getservbyport函数用于根据给定端口号和可选协议查找相应服务。

#include <netdb.h>
struct servent *getserbyport(int port,const char *protoname);

注意:参数port必须为网络字节序

本函数的典型调用如下:

struct servent *sptr;
sptr = getservbyport(htons(53),"udp"); /* DNS using UDP */
sptr = getservbyport(htons(21),"tcp"); /*FTP using TCP */
sptr = getservbyport(htons(21),NULL); /* FTP using TCP */
sptr = getservbyport(htons(21),"udp"); /* this call will fial */

因为UDP上没有服务使用端口21,所以最后一个调用将失败。

必须清楚的是,有些端口号在TCP上用于一种服务,在UDP上却用于完全不同的另一个服务。例如:

huangcheng@ubuntu:~$ grep 514 /etc/services
shell 514/tcp cmd # no passwords used
syslog 514/udp

表明端口514在TCP上由rsh命令使用,在UDP上却由syslog守护进程使用。

UNIX网络编程——名字与地址转换(gethostbyname,gethostbyaddr,getservbyname,getservbyport,getaddrinfo,getnameinfo函数)的更多相关文章

  1. UNIX网络编程 第6章 I/O复用:select和poll函数

    UNIX网络编程 第6章 I/O复用:select和poll函数

  2. python网络编程——将IPv4地址转换成不同的格式

    1.将IPv4地址转换为32位二进制格式,用做底层网络函数. import socket from binascii import hexlify def convert_IPv4_address() ...

  3. Unix网络编程 之 基本套接字调用(一)

    Unix/Linux支持伯克利风格的套接字编程,它同一时候支持面向连接和面向无连接类型的套接字. 套接字最经常使用的一些系统调用: socket() bind() connect() listen() ...

  4. UNP第11章——名字与地址转换

    1.域名系统 程序中只使用主机名和服务名的好处是,如果IP或端口变化,只需要改变映射关系,不需要重新编译程序. 1.1 资源记录 DNS的条目为资源记录,有用的项如下: A IPv4地址 AAAA I ...

  5. 《Unix 网络编程》11:名字和地址转换

    名字和地址转换 系列文章导航:<Unix 网络编程>笔记 域名系统 简介 域名系统主要用于主机名字和 IP 地址之间的映射.主机名可以是: 简单名字,如:centos01 全限定域名(FQ ...

  6. UNIX网络编程——套接字选项(心跳检测、绑定地址复用)

    /* 设置套接字选项周期性消息检测连通性 心跳包. 心博.主要用于长连接. * 参数:套接字, 1或0开启, 首次间隔时间, 两次间隔时间, 断开次数 */ void setKeepAlive( in ...

  7. UNIX网络编程-基本API介绍(二)

    参考链接:http://www.cnblogs.com/riky/archive/2006/11/24/570713.aspx 1.getsockname和getpeername getsocknam ...

  8. 【LINUX/UNIX网络编程】之使用消息队列,信号量和命名管道实现的多进程服务器(多人群聊系统)

    RT,使用消息队列,信号量和命名管道实现的多人群聊系统. 本学期Linux.unix网络编程的第三个作业. 先上实验要求: 实验三  多进程服务器 [实验目的] 1.熟练掌握进程的创建与终止方法: 2 ...

  9. Unix网络编程--卷一:套接字联网API

    UNIX网络编程--卷一:套接字联网API 本书面对的读者是那些希望自己编写的程序能够使用成为套接字(socket)的API进行彼此通信的人. 目录: 0.准备环境 1.简介 2.传输层:TCP.UD ...

随机推荐

  1. bzoj3294[Cqoi2011]放棋子 dp+组合+容斥

    3294: [Cqoi2011]放棋子 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 755  Solved: 294[Submit][Status] ...

  2. 勤拂拭软件 java web 开发教程(1) - 开发环境搭建

    勤拂拭软件系列教程 之 Java Web开发之旅(1) Java Web开发环境搭建 1 前言 工作过程中,遇到不少朋友想要学习jsp开发,然而第一步都迈不出,连一个基本的环境都没有,试问,如何能够继 ...

  3. 基于Mapxtreme for JAVA的电子地图设计与实现

    基于Mapxtreme for JAVA的电子地图设计与实现学生毕业设计,适合测绘类专业研究目标:        开发一个基于MapXtreme for JAVA的校园电子地图项目,使用MapInfo ...

  4. 关于InnoDB的读写锁类型以及加锁方式

    (本文为了方便,英文关键词都都采用小写方式,相关知识点会简单介绍,争取做到可以独立阅读) 文章开始我会先介绍本文需要的知识点如下: innodb的聚簇索引(聚集索引)和非聚簇索引(二级索引.非聚集索引 ...

  5. java 学习笔记2 面向对象(上)

    类和对象 类是某一批对象的抽象,可以把类理解成某种概念.对象是一个具体存在的实体.类和对象是面向对象的核心. 类定义的是多个实例的特征,类不是具体存在,实例才是具体存在. 定义类(class)的语法: ...

  6. ftp:connect:未知错误号

    Linux下使用ftp命令时,提示:ftp: connect :未知错误号解决方法:service iptables stop或/etc/rc.d/init.d/iptables stop

  7. AutoMagic-开源自动化平台构建思路

    最近在github上看到AutoMagic自动化平台开源了,一时手痒,就试着搭了一套环境,现在把思路和大家说一说. AutoMagic从其工作分工分两部分: 1:Web端管理平台 管理平台基于Pyth ...

  8. MongoDB 高级索引

    考虑以下文档集合(users ): { "address": { "city": "Los Angeles", "state&qu ...

  9. Linux(八)用户管理

    8.1 基本介绍 Linux系统是一个多用户多任务的操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账户,然后以这个账户身份进入系统. Linux的用户需要至少要属于一个组. 8 ...

  10. java中static特殊性和final(static成员直接被访问,this不能用在static方法中,static不可访问非static)

    java的static关键字 java中,static修饰的成员变量和成员方法叫静态变量和静态方法,不依赖类特定的实例,被类的所有实例共享. 静态变量或类变量 和 实例变量,区别是: 静态变量在内存中 ...