一、服务与地址的关系

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

  • 赋予各个服务的端口号规范列表由IANA通过http://www.iana.org/assignments/port-num-bers维护。/etc/services文件通常包含由IANA维护的规范赋值列表的某个子集

二、struct  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 */
}

参数

  • s_name:服务的官方名称
  • s_aliases:服务别名列表
  • s_port:服务对应的端口号
  • s_proto:与此服务一起使用的协议的名称

三、getservbyname

#include <netdb.h>
struct servent *getservbyname(const char *servname, const char *protoname);
  • 功能:通过服务名与服务的协议类型返回一个struct servent结构体信息

参数

  • 参数1:服务的名称
  • 参数2:服务对应的协议类型

返回值

  • 成功:返回struct servent结构体指针
  • 失败:返回NULL

参数使用的注意事项

  • 参数1必须指定,参数2可以选择忽略或指定

    • 如果protoname指定:如果同时指定了协议(即protoname参数为非空指针),那么指定服务必须有匹配的协议。有些因特网服务既用TCP也用UDP提供(例如DNS),其他因特网服务则仅仅支持单个协议(例如FTP要求使用TCP,而不能使用UDP)
    • 如果protoname未指定:如果protoname未指定而servname指定服务支持多个协议,那么返回哪个端口号取决于实现。通常情况下这种选择无关紧要,因为支持多个协议的服务往往使用相同的TCP端口号和UDP端口号,不过这点 并没有保证
  • 例如:既然FTP仅仅支持TCP,第二个调用和第三个调用等效,第四个调用则会失败
struct servent *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 */ 

演示案例

//程序传入主机名和服务名,先根据主机名得到IP
//然后根据服务名获得端口。然后创建一个套接字连接这个IP和端口对应的服务
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include<string.h>
#include<netdb.h>
#define MAXLINE 1024int Socket(int domain,int type,int protocal);int main(int argc, char **argv)
{int                    sockfd, n;char              recvline[MAXLINE + 1];struct sockaddr_in   servaddr;struct in_addr     **pptr;struct in_addr       *inetaddrp[2];struct in_addr        inetaddr;struct hostent     *hp;          //保存主机信息struct servent        *sp;          //保存服务信息if (argc != 3){perror("usage: daytimetcpcli1 <hostname> <service>");exit(1);}//通过域名解析获得主机的信息if ( (hp = gethostbyname(argv[1])) == NULL)//如果没有解析到{if (inet_aton(argv[1], &inetaddr) == 0) {//将字符串IP转为网络IPprintf("hostname error for %s: %s\n", argv[1], hstrerror(h_errno));exit(2);} else {//转换的网络IP存放在inetaddrp[0]中inetaddrp[0] = &inetaddr;inetaddrp[1] = NULL;pptr = inetaddrp;}} //将解析到的IP地址列表给pptrelse {pptr = (struct in_addr **) hp->h_addr_list;}//解析服务信息if ((sp = getservbyname(argv[2], "tcp")) == NULL){printf("getservbyname error for %s\n", argv[2]);exit(3);}//尝试连接这个服务for ( ; *pptr != NULL; pptr++){sockfd = Socket(AF_INET, SOCK_STREAM, 0);bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_port = sp->s_port;memcpy(&servaddr.sin_addr, *pptr, sizeof(struct in_addr));printf("trying %s\n",inet_ntoa((struct in_addr)servaddr.sin_addr));//连接服务if (connect(sockfd, (struct sockaddr*) &servaddr, sizeof(servaddr)) == 0)break; //连接成功就breakperror("connect error");close(sockfd);}if (*pptr == NULL){perror("unable to connect");exit(5);}while ((n = read(sockfd, recvline, MAXLINE)) > 0) {recvline[n] = 0;fputs(recvline, stdout);}exit(0);
}int Socket(int domain,int type,int protocal)
{int sockFd=socket(domain,type,protocal);if(sockFd<0){perror("socket");exit(4);}return sockFd;
}

四、getservbyport

#include <netdb.h>
struct servent *getservbyport(int port, const char *proto);//返回值:成功返回struct servent结构体指针;失败返回NULL
  • 功能:通过端口号与端口对应的服务协议类型返回一个struct servent结构体信息

注意

  • 注意事项一:参数1必须为网络字节序的端口号
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 fail */ 
  • 注意事项二:一个端口可能有多种协议类型,因此参数2对应于不同的协议类型,返回的信息也不同

    • 必须清楚的是,有些端口号在TCP上用于一种服务,在UDP上却用于完全不同的另一种服 务。例如:表明端口514在TCP上由rsh命令使用,在UDP上却由syslog守护进程使用。512~514范围内的端口都有这个特性

UNP编程:31---名字与地址转换之(服务解析函数:getservbyname()、getservbyport()、struct  servent)相关推荐

  1. 网络编程学习——名字与地址转换(一)

    2019独角兽企业重金招聘Python工程师标准>>> 1 域名系统 域名系统(Domain Name System,DNS)主要用于主机名字与IP地址之间的映射.主机名既可以是一个 ...

  2. UNP总结 Chapter 11 名字与地址转换

    本章讲述在名字和数值地址间进行转换的函数:gethostbyname和gethostbyaddr在主机名字与IP地址间进行转换,getservbyname和getservbyport在服务器名字和端口 ...

  3. Unix网络编程学习笔记之第11章 名字与地址转换

    一. 域名系统(DNS) 1. 简介 DNS主要用于主机名和IP地址之间的映射. 主机名可以是简单的名字ljm,也可以是全限定域名ljm.localdomainbaidu.com等. 2.资源记录 D ...

  4. 《UNIX网络编程:套接字联网API》啃书笔记(第8UDP套接字编程、11章地址转换)

    基本UDP套接字编程 下图为UDP客户/服务器程序的函数调用: 注意客户不与服务器建立连接,而是只管使用sendto函数给服务器发送数据报,其中必须指定目的地的地址作为参数.类似的,服务器不接受来自客 ...

  5. 名字与地址转换getservbyname 与 getservbyport函数

    名字与地址转换getservbyname 与 getservbyport函数 服务也通常靠名字来标志,getservbyname函数用于根据给定名字查找相应服务. #include struct    ...

  6. UNP Chapter 9 - 基本名字与地址转换

    9.1. 概述 本章讲述在名字和数值地址间进行转换的函数:gethostbyname和gethostbyaddr在主机名字与IP地址间进行转换,getservbyname和getservbyport在 ...

  7. 二进制转换为十进制c语言编程,将二进制IP地址转换成十进制(C语言程序实现)

    将二进制IP地址转换成十进制(C语言程序实现) /* * Name: IP Address * Funcion: To convert binary numbers to decimal number ...

  8. UNP Chapter 11 - 高级名字与地址转换

    11.1. 概述 函数gethostbyname和gethostbyaddr是依赖于协议的,使用前一个函数时,我们必须知道放置结果的套接口地址结构的成员是哪一种(举例来说,IPv4使用sin_addr ...

  9. UNP编程:29---名字与地址转换之(域名系统)

    一.域名系统的概念 域名系统(Domain Name System,DNS)主要用于主机名字与IP地址之间的映射. 主机名既可以是一个简单名字(simple name),例如solaris或bsdi, ...

  10. (域名、主机名、服务名、端口号)名字与地址的转换 (gethostbyname、getservbyname、getaddrinfo、getnameinfo等)

    转载地址 本章讲述在名字和数值地址间进行转换的函数:gethostbyname和gethostbyaddr在主机名字与IP地址间进行转换,getservbyname和getservbyport在服务器 ...

最新文章

  1. ArXiv 2020 | 抖音“变身漫画”滤镜背后的技术,难道来自这篇论文?
  2. sql server无效的对象名称 - 但表列在SSMS表列表中
  3. 【转】linux tar 压缩
  4. 后年将有60亿部手机!
  5. Hive的两种操作模式
  6. nhibernate:composite-id class must override Equals()
  7. FLV封装格式介绍及解析
  8. 计算机的科学原理是什么,人工智能的工作原理是什么?
  9. 展望Java的未来:空值类型
  10. 字节流转化为文件流_C#文件转换为字节流及字节流转换为文件
  11. 6大设计原则之接口隔离原则
  12. 前锋php人工智能_人工智能除了学习php,还应该学什么?
  13. arduino蜂鸣器音乐代码青花瓷_教你用 Arduino 制造简易金属探测器
  14. [汇编学习笔记][第十六章直接定址表]
  15. php利用svn hooks将程序自动发布到测试环境
  16. laravel框架使用phpQuery库来实现网页抓取
  17. java wps linux 安装_安装wps for linux无法启动
  18. 详解Guitar Pro 7小节的组织定义
  19. directdraw(directdraw怎么开启)
  20. php识别word语言,PHP读取word文档

热门文章

  1. 使用html语言实现学生成绩表展示
  2. GPUImage.h简单说明
  3. 白盒测试及其基本方法
  4. 全球及中国InGaAs APD阵列行业研究及十四五规划分析报告
  5. 转:石康 不奋斗的姑娘我不爱
  6. layui文件上传(头像上传)
  7. 社交类产品创业难点在哪儿?
  8. 关于编译型语言函数的调用(一)
  9. 【soft6星评论】站在5G时代的入口,我们看到了“智慧交通”的含苞待放
  10. 迷宫算法总结(最短路径)BFS宽度优先