第七章 面向连接的协议──客户端
一、/etc/services文件
1、这个文件将某个特定的Internet服务名映射到协议的端口号,它的路径名可以通过C语言的宏_PATH_SERVICES得到,如:
#include <netdb.h>
printf("File is path:'%s'/n", _PATH_SERVICES)
2、可用的函数
2.1
getservent(3)
#include <netdb.h>
struct servent *getservent(void)
返回值是指向/etc/services文件中某一条目的结构指针,当文件结束时返回NULL,如果发生错误也返回NULL,错误信息可以通过errno查看。
struct servent{
char *s_name; //服务名
char **s_aliases; //别名清单
int s_port; //端口号
char *s_proto; //使用的协议
}
* 注意 s_port的值是网络字节序,所以在打印时要将其转换为主机字节序:ntohs(sp->s_port)
应用代码见:p122.c
2.2
setservent(3)
#include <netdb.h>
void setservent(int stayopen)
作用:回到/etc/services文件的开始处
stayopen:非0时,表示不需要重新打开/etc/services文件,只是回到文件头部
stayopen:为0时,表示它将先关闭已经打开的/etc/services文件,然后再重新打开,为调用getservent()做准备。
2.3
endservent(3)
#include <netdb.h>
void endservent(void)
当使用getservent()时在后台自动打开/etc/services,endservent()则关闭文件。
2.4
getservbyname(3)
#include <netdb.h>
struct servent *getservbyname(const char *name, const char *proto)
通过名字和协议查询服务
name:要查询的服务名称,如telnet
proto:要查询的协议,如tcp
没有找到返回NULL,否则返回一个指向servent结构的指针。下面是一个小例子:
struct servent *sp;
sp = getservbyname("telnet", "tcp");
if (!sp)
abort();
2.5
getservbyport(3)
#include <netdb.h>
struct servent *getservbyport(int port, const char *proto)
通过端口和协议查询服务
port:端口号
proto:协议名,如tcp
没有找到返回NULL,否则返回一个指向servent结构的指针。
二、/etc/protocols文件
1、这个文件是一个包含已定义的Internet协议值的小型数据库
2、可用的函数
2.1
getprotoent(3)
#include <netdb.h>
struct protoent *getprotoent(void)
返回值是指向/etc/protocols文件中某一条目的结构指针,当文件结束时返回NULL,如果发生错误也返回NULL,错误信息可以通过errno查看。
struct protoent{
char *p_name; //协议名,如"tcp"
char **p_aliases; //别名清单:如果pp是一个结构体指针那么pp->p_aliases[0]就是一个字符串,如"TCP"
char *p_proto; //协议号:本文件中tcp的协议号与C宏IPPROTO_TCP的定义是一致的
}
可以查看/usr/include/netinet/in.h和本文件
应用代码见:p127.c
2.2
setprotoent(3)
#include <netdb.h>
void setprotoent(int stayopen)
作用:回到/etc/services文件的开始处
stayopen:非0时,表示不需要重新打开/etc/protocols文件,只是回到文件头部
stayopen:为0时,表示它将先关闭已经打开的/etc/protocols文件,然后再重新打开,为调用getprotoent()做准备。
2.3
endprotoent(3)
#include <netdb.h>
void endprotoent(void)
当使用getprotoent()时在后台自动打开/etc/protocols,endprotoent()则关闭文件。
2.4
getprotobyname(3)
#include <netdb.h>
struct protoent *getprotobyname(const char *name)
通过名字和协议查询服务
name:要查询的服务名称,如telnet
proto:要查询的协议,如tcp
没有找到返回NULL,否则返回一个指向servent结构的指针。下面是一个小例子:
struct servent *sp;
sp = getservbyname("telnet", "tcp");
if (!sp)
abort();
2.5
getservbyport(3)
#include <netdb.h>
struct servent *getservbyport(int port, const char *proto)
通过端口和协议查询服务
port:端口号
proto:协议名,如tcp
没有找到返回NULL,否则返回一个指向servent结构的指针。
p122.c
p127.c
一、/etc/services文件
1、这个文件将某个特定的Internet服务名映射到协议的端口号,它的路径名可以通过C语言的宏_PATH_SERVICES得到,如:
#include <netdb.h>
printf("File is path:'%s'/n", _PATH_SERVICES)
2、可用的函数
2.1
getservent(3)
#include <netdb.h>
struct servent *getservent(void)
返回值是指向/etc/services文件中某一条目的结构指针,当文件结束时返回NULL,如果发生错误也返回NULL,错误信息可以通过errno查看。
struct servent{
char *s_name; //服务名
char **s_aliases; //别名清单
int s_port; //端口号
char *s_proto; //使用的协议
}
* 注意 s_port的值是网络字节序,所以在打印时要将其转换为主机字节序:ntohs(sp->s_port)
应用代码见:p122.c
2.2
setservent(3)
#include <netdb.h>
void setservent(int stayopen)
作用:回到/etc/services文件的开始处
stayopen:非0时,表示不需要重新打开/etc/services文件,只是回到文件头部
stayopen:为0时,表示它将先关闭已经打开的/etc/services文件,然后再重新打开,为调用getservent()做准备。
2.3
endservent(3)
#include <netdb.h>
void endservent(void)
当使用getservent()时在后台自动打开/etc/services,endservent()则关闭文件。
2.4
getservbyname(3)
#include <netdb.h>
struct servent *getservbyname(const char *name, const char *proto)
通过名字和协议查询服务
name:要查询的服务名称,如telnet
proto:要查询的协议,如tcp
没有找到返回NULL,否则返回一个指向servent结构的指针。下面是一个小例子:
struct servent *sp;
sp = getservbyname("telnet", "tcp");
if (!sp)
abort();
2.5
getservbyport(3)
#include <netdb.h>
struct servent *getservbyport(int port, const char *proto)
通过端口和协议查询服务
port:端口号
proto:协议名,如tcp
没有找到返回NULL,否则返回一个指向servent结构的指针。
二、/etc/protocols文件
1、这个文件是一个包含已定义的Internet协议值的小型数据库
2、可用的函数
2.1
getprotoent(3)
#include <netdb.h>
struct protoent *getprotoent(void)
返回值是指向/etc/protocols文件中某一条目的结构指针,当文件结束时返回NULL,如果发生错误也返回NULL,错误信息可以通过errno查看。
struct protoent{
char *p_name; //协议名,如"tcp"
char **p_aliases; //别名清单:如果pp是一个结构体指针那么pp->p_aliases[0]就是一个字符串,如"TCP"
char *p_proto; //协议号:本文件中tcp的协议号与C宏IPPROTO_TCP的定义是一致的
}
可以查看/usr/include/netinet/in.h和本文件
应用代码见:p127.c
2.2
setprotoent(3)
#include <netdb.h>
void setprotoent(int stayopen)
作用:回到/etc/services文件的开始处
stayopen:非0时,表示不需要重新打开/etc/protocols文件,只是回到文件头部
stayopen:为0时,表示它将先关闭已经打开的/etc/protocols文件,然后再重新打开,为调用getprotoent()做准备。
2.3
endprotoent(3)
#include <netdb.h>
void endprotoent(void)
当使用getprotoent()时在后台自动打开/etc/protocols,endprotoent()则关闭文件。
2.4
getprotobyname(3)
#include <netdb.h>
struct protoent *getprotobyname(const char *name)
通过名字和协议查询服务
name:要查询的服务名称,如telnet
proto:要查询的协议,如tcp
没有找到返回NULL,否则返回一个指向servent结构的指针。下面是一个小例子:
struct servent *sp;
sp = getservbyname("telnet", "tcp");
if (!sp)
abort();
2.5
getservbyport(3)
#include <netdb.h>
struct servent *getservbyport(int port, const char *proto)
通过端口和协议查询服务
port:端口号
proto:协议名,如tcp
没有找到返回NULL,否则返回一个指向servent结构的指针。
p122.c
#include
<
stdio.h
>
#include < stdlib.h >
#include < errno.h >
#include < string .h >
#include < netdb.h >
#include < unistd.h >
int main( int argc, char * argv[])
{
int x;
struct servent *sp;
for (;;)
{
errno = 0;
if (!(sp = getservent()))
break;
printf("%s: "
" Port: %d "
" Protocol: %s "
" Aliases:",
sp->s_name, ntohs(sp->s_port), sp->s_proto);
for (x = 0; sp->s_aliases[x] != NULL; ++x)
{
printf("%s", sp->s_aliases[x]);
}
putchar(' ');
}
printf("File is path: '%s' ", _PATH_SERVICES);
if (errno != 0 && errno != ENOENT)
fprintf(stderr, "%s:getservent(3) %d ", strerror(errno), errno);
return 0;
}
#include < stdlib.h >
#include < errno.h >
#include < string .h >
#include < netdb.h >
#include < unistd.h >
int main( int argc, char * argv[])
{
int x;
struct servent *sp;
for (;;)
{
errno = 0;
if (!(sp = getservent()))
break;
printf("%s: "
" Port: %d "
" Protocol: %s "
" Aliases:",
sp->s_name, ntohs(sp->s_port), sp->s_proto);
for (x = 0; sp->s_aliases[x] != NULL; ++x)
{
printf("%s", sp->s_aliases[x]);
}
putchar(' ');
}
printf("File is path: '%s' ", _PATH_SERVICES);
if (errno != 0 && errno != ENOENT)
fprintf(stderr, "%s:getservent(3) %d ", strerror(errno), errno);
return 0;
}
p127.c
#include
<
stdio.h
>
#include < stdlib.h >
#include < errno.h >
#include < string .h >
#include < netdb.h >
#include < unistd.h >
int main( int argc, char * argv[])
{
int x;
struct protoent *pp;
for (;;)
{
errno = 0;
if (!(pp = getprotoent()))
break;
printf("%s: "
" Protocol: %d "
" Aliases:",
pp->p_name, pp->p_proto);
for (x = 0; pp->p_aliases[x] != NULL; ++x)
{
printf("%s", pp->p_aliases[x]);
}
putchar(' ');
}
if (errno != 0 && errno != ENOENT)
fprintf(stderr, "%s:getprotoent(3) %d ", strerror(errno), errno);
return 0;
}
#include < stdlib.h >
#include < errno.h >
#include < string .h >
#include < netdb.h >
#include < unistd.h >
int main( int argc, char * argv[])
{
int x;
struct protoent *pp;
for (;;)
{
errno = 0;
if (!(pp = getprotoent()))
break;
printf("%s: "
" Protocol: %d "
" Aliases:",
pp->p_name, pp->p_proto);
for (x = 0; pp->p_aliases[x] != NULL; ++x)
{
printf("%s", pp->p_aliases[x]);
}
putchar(' ');
}
if (errno != 0 && errno != ENOENT)
fprintf(stderr, "%s:getprotoent(3) %d ", strerror(errno), errno);
return 0;
}