网络编程学习笔记(getservbyname和getservbyport函数)
来源:互联网 发布:网络推广框架协议 编辑:程序博客网 时间:2024/05/17 03:24
通过服务器的名字而不是服务器端口号来认知它,而且如果从主机到端口号的映射包含在一个文件中(一般是/etc/services),则如果端口号改变,我们所需做的所有改动就是改动文件/etc/services中的一行,而不是重新编译应用程序。
getservbyname函数原型为:
#include <netdb.h>struct servent *getservbyname(const char *servname, const char *protoname);成功返回非空指针,失败返回空指针
此函数返回一个指向下面所示结构的指针:
struct servent{ char *s_name; //official service name char **s_aliases; // alias list int s_port;// port number, network-byte order char *s_proto;// protocol to use};
服务名必须指定,如果指定了一个协议(即protoname为非空指针),则结果表项也必须有匹配的协议。如果protoname没有指定且服务支持多个协议,则返回哪个端口是依赖于实现的。一般来说这没有关系,因为支持多个协议的服务常常使用相同的TCP和UDP端口号,但并没有保证
结构servent中我们关心的主要成员是端口号,由于端口号是以网络字节序返回的,在将它存储于套接口地址结构时,绝对不能调用htons
对此函数的典型调用是:
struct servent *sptr;sptr = getservbyname("domain", "udp"); // DNS using UDPsptr = getservbyname("ftp", "tcp");//FTP using TCPsptr = getservbyname("ftp", NULL); //FTP using TCPsptr = 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 UDPsptr = getservbyport(htons(21), "tcp");//FTP using TCPsptr = getservbyport(htons(21), NULL);//FTP using TCPsptr = 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;}
输出为:
0 0
- 网络编程学习笔记(getservbyname和getservbyport函数)
- getservbyname和getservbyport
- Unix网络编程卷1第11章 名字与地址转换getservbyname 与 getservbyport函数
- UNIX网络编程——名字与地址转换(gethostbyname,gethostbyaddr,getservbyname,getservbyport,getaddrinfo,getnameinfo函数)
- linux网络编程五:gethostbyname, getservbyname
- 网络编程学习笔记(getsockopt和setsockopt函数)
- 网络编程学习笔记(recvfrom和sendto函数)
- 网络编程学习笔记(recv和send函数)
- 网络编程学习笔记(readv和writev函数)
- 网络编程学习笔记(recvmsg和sendmsg函数)
- 网络编程学习笔记(poll函数)
- 网络编程学习笔记(gethostbyname函数)
- 网络编程学习笔记(gethostbyaddr函数)
- 网络编程学习笔记(uname函数)
- 网络编程学习笔记(gethostname函数)
- 网络编程学习笔记(getaddrinfo函数)
- 网络编程学习笔记(gai_strerror函数)
- 网络编程学习笔记(freeaddrinfo函数)
- 九月学习感想
- Win7下Qt532+MinGW482+OpenCV249+Cmake302编译环境搭建
- QuadCurveMenu菜单值得拥有
- Codeforces Round #271 (Div. 2) E Pillars(dp+线段树优化)
- 使用Junit对Java Web项目白盒测试
- 网络编程学习笔记(getservbyname和getservbyport函数)
- poj 3255 spfa(求次短路)
- 32个重要算法总结
- java枚举使用详解
- 在linux下编译DeepBoosting(在win7下实现)
- 22 款精选漂亮免费的扁平化风格及简单线条图标设计素材 (合集打包下载)
- Oracle中创建、修改、删除序列
- 新班级趣事
- 字符串操作