通过服务器的名字而不是服务器端口号来认知它,而且如果从主机到端口号的映射包含在一个文件中(一般是/etc/services),则如果端口号改变,我们所需做的所有改动就是改动文件/etc/services中的一行,而不是重新编译应用程序。

getservbyname函数原型为:

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

成功返回非空指针,失败返回空指针

此函数返回一个指向下面所示结构的指针:

struct servent
{char *s_name;     //official service namechar **s_aliases;    // alias listint s_port;// port number, network-byte orderchar *s_proto;// protocol to use
};

服务名必须指定,如果指定了一个协议(即protoname为非空指针),则结果表项也必须有匹配的协议。如果protoname没有指定且服务支持多个协议,则返回哪个端口是依赖于实现的。一般来说这没有关系,因为支持多个协议的服务常常使用相同的TCP和UDP端口号,但并没有保证

结构servent中我们关心的主要成员是端口号,由于端口号是以网络字节序返回的,在将它存储于套接口地址结构时,绝对不能调用htons

对此函数的典型调用是:

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

由于FTP仅支持TCP,所以第二个和第三个调用 是相同的,第四个调用将失败。

下一个函数getservbyport在给定端口号和可选协议后查找相应的服务

#include <netdb.h>
struct servent *getservbyport(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 fail

代码如下:

#include <netdb.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>#define MAXLINE 128char *sock_ntop(const struct sockaddr* sa, socklen_t salen)
{char portstr[7];static char str[MAXLINE];switch (sa->sa_family) {case AF_INET:  {struct sockaddr_in *sin = (struct sockaddr_in*)sa;if (inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str)) == NULL) return NULL;if (ntohs(sin->sin_port) != 0) {snprintf(portstr, sizeof(portstr), ".%d", ntohs(sin->sin_port));strcat(str, portstr);}return str;}}
}int main(int argc, char **argv)
{int sockfd, n;char recvline[MAXLINE + 1];struct sockaddr_in servaddr;struct in_addr **pptr;struct hostent *hp;struct servent *sp;if (argc != 3) {printf("usage: execname <hostname> <service> \n");return -1;}if ((hp = gethostbyname(argv[1])) == NULL) {printf("hostname error for %s:%s\n", argv[1],  hstrerror(h_errno));return -1;}if ((sp = getservbyname(argv[2], "tcp")) == NULL) {printf("getservbyname error for %s:%s\n", argv[2], hstrerror(h_errno));return -1;}pptr = (struct in_addr**)hp->h_addr_list;for (; *pptr != NULL; pptr++) {sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0) {printf("socket error:%s\n", strerror(errno));return -1;}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("addr=%s, port=%d\n", inet_ntoa(**pptr), ntohs(sp->s_port));printf("trying %s\n", sock_ntop((struct sockaddr*)&servaddr, sizeof(servaddr)));if (connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == 0) break;printf("connect error:%s\n", strerror(errno));close(sockfd);}    if (*pptr == NULL) {printf("unable to connect\n");return -1;}while ((n = read(sockfd, recvline, MAXLINE)) > 0) {recvline[n] = 0;fputs(recvline, stdout);}return 0;
}

输出为:

网络编程学习笔记(getservbyname和getservbyport函数)相关推荐

  1. 网络编程学习笔记(recv和send函数)

    与read和write函数相似,只是多了一个附加的参数,其函数原型为: #include <sys/socket.h> ssize_t recv(int sockfd, void *buf ...

  2. 网络编程学习笔记(recvmsg和sendmsg函数)

    这两个函数是最通用的I/O函数.实际上,可以用recvmsg代替read.readv.recv和redvfrom.同样,各种输出函数都可以用sendmsg取代 #include<sys/sock ...

  3. 网络编程学习笔记(readv和writev函数)

    这两个函数与read和write相似,但readv和writev可以让我们在一个函数调用中读取多个缓冲区,这些操作被称为分散读和集中写.其函数原型为: #include <sys/uio.h&g ...

  4. 网络编程学习笔记(UDP的connect函数)

    对于已连接的UDP套接口,发生了三个变化: 1.再也不能给输出操作指定目的IP地址和端口,也就是说,不能再调用 sendto,而使用send或者write.写到已连接UDP套接口上的任何东西都自动发送 ...

  5. 网络编程学习笔记(recvfrom和sendto函数)

    其原型为: #include <sys/socket.h>ssize_t recvfrom(int sockfd, void *buff, size_t nbytes, int flags ...

  6. 网络编程学习笔记(getsockopt和setsockopt函数)

    其原型为: #include <sys/socket.h> int getsockopt(int sockfd, int level, int optname, void *optval, ...

  7. java 网络编程学习笔记

    java 网络编程学习笔记 C/S模式:客户端和服务器 客户端创建流程 1 1.建立Socket端点 2 3 Socket s = new Socket(绑定地址, 绑定端口); 2.确认源数据方式和 ...

  8. [Linux网络编程学习笔记]索引

    一.Linux基本知识 [学习笔记]Linux平台的文件I/O操作 [学习笔记]Linux平台的文件,目录及操作 [Linux学习笔记]标准输入输出 [Linux学习笔记]进程概念及控制 [Linux ...

  9. 编程开发:Linux网络编程学习笔记

    非常全面.通俗易懂.值得借鉴的Linux网络编程学习笔记.关键字:linux linux编程 网络编程 linux网络编程 下载地址:点我下载 特别说明:本资源收集于网络,版权归原作者及版权商所有,仅 ...

最新文章

  1. 根据STATUS信息对MySQL进行优化
  2. JQuery笔记(二)jq常用方法animate()
  3. 老司机带你深入浅出 Collection
  4. MATLAB实战系列(三十八)-基于K-means聚类算法的MATLAB图像分割
  5. 关于Mybatis,我总结了 10 种通用的写法
  6. OpenCV cv :: Mat的串行输出功能的实例(附完整代码)
  7. MAC MAMP 中安装配置使用 ThinkPHP
  8. Sublime Text for Mac 如何格式化代码
  9. 基于Ganos百行代码实现亿级矢量空间数据在线可视化
  10. c#上传文件程序在本地测试没问题发布到服务器上就,高分求助!!!C#为什么程序在本地运行没有问题,但布署到服务器上后就不行了呢...
  11. [hdu1532]最大流
  12. 如何将MySQL卸载干净?
  13. appStore苹果退款通知
  14. Web服务器环境的搭建
  15. 1周上线系统,效率提升100%,宜搭助力阿里巴巴法务数字化升级
  16. uniapp苹果打包白屏 ,安卓没问题,运行也不报错,自定义基座也没问题
  17. 一块宝藏存储芯片【SD NAND】
  18. ios开发所需图片尺寸汇总
  19. 使用gpu服务器搭建人脸识别系统,基于GPU的大规模人脸识别系统的设计与实现
  20. 如何巧妙的防止网站被劫持

热门文章

  1. iOS 百度地图使用详解
  2. Linux的shell变量
  3. tomcat cpu占用过高,系统负载高问题跟踪
  4. 把在win7系统下,把笔记本的无线网卡变成路由器,共享上网。
  5. Visual Studio 2008 + Visual Assist X的CUDA2.3编译环境设置[转]
  6. mysql odbc 安装配置过全过程
  7. python创意编程比赛-报名了!2019年全国青少年创意编程与智能设计大赛报名开始了...
  8. 给python初学者的最好练手项目-Python的练手项目有哪些值得推荐?(知乎转载)...
  9. python turtle库画图案-python之绘制图形库turtle(转)
  10. monty python-网易云音乐