Linux学习笔记31——网络信息

一 主机数据库函数

#include <netdb.h>
struct hostent *gethostbyaddr(const void *addr,      //地址
                  size_t len,          //长度
                  int type           //类型
                 );
struct hostent *gethostbyname(const char *name);

  这些函数返回的结构中至少包含以下几个成员

struct hostent{
    char *h_name;          //主机名称
    char **h_aliases;        //别名列表
    int h_addrtype;         //地址类型
    int h_length;          //地址长度
    char **h_addr_list;      //地址列表
};

  如果想获得某台计算机的主机数据库信息,可以调用gethostbyname函数并且将结果打印出来,注意,要把返回的地址列表转换为正确的地址类型,并用函数inet_ntoa将它们从网络字节序转换为可打印的字符串

#include <arpa/inet.h>
char *inet_ntoa(struct in_addr in);

函数作用:将一个因特网主机地址转换为一个点分四元组格式的字符串

#include <unistd.h>
int gethostname(char *name,int namelength);

函数作用:将当前主机的名字写入name指向的字符串中。主机名为null结尾。参数namelength指定了字符串name的长度,如果返回的主机名太长,它就会被截断

例子:

#include <stdio.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <netdb.h>
#include <netinet/in.h>

int main(int argc,char *argv[]){
    char *host,**names,**addrs;
    struct hostent *hostinfo;
    //把host变量设置为getname程序所提供的命令行参数,或默认设置为用户主机的主机名
    if(argc==1){
        char myname[256];
        gethostname(myname,255);
        host=myname;
    }else{
        host=argv[1];
    }
    //调用gethostbyname,如果未找到相应的信息就报告一条错误
    hostinfo=gethostbyname(host);
    if(!hostinfo){
        sprintf(stderr,"Cannot get info for host:%s\n",host);
        exit(1);
    }
    //显示主机名和它可能有的所有别名
    printf("result for host:%s\n",host);
    printf("Name:%s\n",hostinfo->h_name);
    printf("Aliases:");
    names=hostinfo->h_aliases;
    while(*names){
        printf("%s",*names);
        names++;
    }
    printf("\n");
    if(hostinfo->h_addrtype!=AF_INET){
        fprintf(stderr,"not an IP host!\n");
        exit(1);    
    }
    addrs=hostinfo->h_addr_list;
    while(*addrs){
        printf("%s",inet_ntoa(*(struct in_addr*)*addrs));
        addrs++;
    }
    printf("\n");
    exit(0);
}

 


二 服务信息函数

#include <netdb.h>
struct servent *getservbyname(const char *name,        //服务名称
                  const char *proto        //指定用于连接该服务的协议,它的取值是tcp(用于SOCK_SREAM类型的TCP连接)和udp(用于SOCK_DGRAM类型的UPD数据报)
                 );
struct servent *getservbyport(int port,             //端口号
                  const char *proto
                 );


结构servent至少包含一下几个成员

struct servent{
    char *s_name;        //服务名称
    char **s_aliases;      //别名列表
    int s_port;         //IP端口号
    char *s_proto;       //服务类型
};

例子:

#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc,char *argv[]){
    char *host;
    int sockfd;
    int len,result;
    struct sockaddr_in address;
    struct hostent *hostinfo;
    struct servent *servinfo;
    char buffer[128];
    
    if(argc==1){
        host="localhost";
    }else{
        host=argv[1];
    }
    //查找主机的地址,如果找不到,就报告一条错误
    hostinfo=gethostbyname(host);
    if(!hostinfo){
        fprintf(stderr,"no host:%s\n",host);
        exit(1);
    }
    //检查主机上是否有daytime服务
    servinfo=getservbyname("daytime","tcp");
    if(!servinfo){
        fprintf(stderr,"no daytime service\n");
        exit(1);
    }
    printf("daytime port is %d\n",ntohs(servinfo->s_port));
    //创建一个套接字
    sockfd=socket(AF_INET,SOCK_STREAM,0);
    //构造connect调用要使用的地址
    address.sin_family=AF_INET;
    address.sin_port=servinfo->s_port;
    address.sin_addr=*(struct in_addr*)*hostinfo->h_addr_list;
    len=sizeof(address);
    //然后建立连接并取得有关信息
    result=connect(sockfd,(struct sockaddr *)&address,len);
    if(result==-1){
        perror("oops:getdate");
        exit(1);
    }
    result=read(sockfd,buffer,sizeof(buffer));
    buffer[result]='\0';
    printf("read %d bytes:%s",result,buffer);
    close(sockfd);
    exit(0);
}

 

posted @ 2014-01-17 19:14  LOSER Z  阅读(391)  评论(0编辑  收藏  举报