学习笔记《实战Linux Socket编程》第七章 面向连接的协议──客户端

来源:互联网 发布:杭州淘宝运营诈骗 编辑:程序博客网 时间:2024/05/14 00:59
第七章  面向连接的协议──客户端

一、/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;
}


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;
}