zoukankan      html  css  js  c++  java
  • 第14章 UDP编程(2)_端口绑定和域名解析

    2. 端口绑定和域名解析

    2.1 端口绑定:SO_REUSEADDR选项

    int opt = 1;//1表示启用该选项
    //设置为可重新使用端口,每次启动该端口时,会重新绑定端口。相当于端口被复位并被重新。
    //绑定。因此,以后以最后这次绑定为准
    if((ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) < 0){
        perror("setsockopt error");
        exit(1);
    }

    2.2 域名解析

    (1)域名解析过程

     

    (2)域名解析函数

    头文件

    #include <netdb.h>

    函数

    struct hostent* gethostent(void);

    struct hostent* gethostbyname(const char* hostname);

    void sethostent(int stayopen);

    void endhostent(void);  //注意get和endhostent应成对使用!

    参数

    struct hostent{
        char*  h_name;     //正式主机名
        char** h_aliases;  //别名,字符串数组
        int    h_addrtype; //协议类型
        int    h_length;   //网络地址大小
        char** h_addr_list;//指向网络地址的指针
    };

    功能

    域名解析

    备注

    查看域名和IP映射关系:#more /etc/hosts

    (3)hostent结构体 

    (4)域名解析案例

    //域名解析,并将结果保存在hostent结构体中
    if((hptr = gethostbyname("www.google.com")) == NULL){
        fprintf(stderr, "gethostbyname call failed.%s
    ", 
                        hstrerror(h_errno));
        return -1;
    }
    
    printf("official name: %s
    ", hptr->h_name); //输出正式名
    for(pptr = hptr->h_aliases; *pptr != NULL; pptr++){ //输出对应各个别名
        printf("	 alias: %s
    ", *pptr);
    }
    
    if(hptr->h_addrtype != AF_INET){   //判断是否为IPv4地址
        fprintf(stderr, "Invalid address type %d
    ", hptr->addrtype);
        return -1;
    }
    
    pptr = hptr->h_addr_list;
    for(; *pptr != NULL; pptr++){    //输出点分十进制的IP地址(字符串)
        printf("	 address: %s
    ", 
                   inet_ntop(hptr->h_addrtype, *pptr, str, sizeof(str)));
    }

    【编程实验】根据域名解析出IP地址

    //gethost.c

    #include <netdb.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <memory.h>
    #include <string.h>
    
    int is_host(struct hostent* host, char* name)
    {
        //如果正式名为name,则直接返回
        if(!strcmp(host->h_name, name)) return 1;
    
        //查找别名为name
        int i = 0;
        while(host->h_aliases[i] != NULL){
            if(!strcmp(host->h_aliases[i], name)) return 1;
            i++;
        }
    }
    
    //根据主机名获取IP
    unsigned int get_ip_by_name(char* name)
    {
        unsigned int ip = 0;
        struct hostent* host;
        //遍历/etc/hosts文件,找出所有的主机名。
        //每调用一次gethostent将读取文件的一行(对应一个主机)
        while((host = gethostent()) != NULL){
            if(is_host(host, name)){
                //h_addr_list[0]中所存放在IP是网络字节序,共4个字节。
                memcpy(&ip, host->h_addr_list[0], 4);
                break;
            }
        }
        endhostent();
        return ip;
    }
    
    void out_addr(struct hostent* h)
    {
        printf("hostname: %s
    ", h->h_name);
        printf("addrtype: %s
    ", h->h_addrtype == AF_INET ? "IPv4": "IPv6");
    
        char ip[16];
        memset(ip, 0, sizeof(ip));
        inet_ntop(h->h_addrtype, h->h_addr_list[0], ip, sizeof(ip));//绑定的第1个IP地址
        printf("ip address: %s
    ", ip);
    
        //别名
        int i = 0;
        while(h->h_aliases[i] != NULL){
            printf("aliases: %s
    ", h->h_aliases[i]);
            i++;
        }
    }
    
    int main(int argc, char* argv[])
    {
        if(argc < 2){
            printf("usage: %s host
    ", argv[0]);
            exit(1);
        }
    
        struct hostent* h;
        h = gethostbyname(argv[1]);
    
        if(h != NULL){
            out_addr(h);
        }else{
            printf("no %s exist
    ", argv[1]);
        }
    
        //根据主机名,输出IP
        unsigned int ipNet = get_ip_by_name(argv[1]); //网络字节序IP
        char ip[16];
        memset(ip, 0, sizeof(ip));
        inet_ntop(AF_INET, &ipNet, ip, sizeof(ip));//绑定的第1个IP地址
        printf("ip address: %s
    ", ip);
    
        return 0;
    }
    /*host文件
     * [root@localhost 14.udp]# more /etc/hosts
     * 127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
     * 192.168.32.100 santaclaus www.5iedu.com
     * ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
     *
     *输出结果
     [root@localhost 14.udp]# bin/gethost santaclaus
     hostname: santaclaus
     addrtype: IPv4
     ip address: 192.168.32.100
     aliases: www.5iedu.com
     ip address: 192.168.32.100
     [root@localhost 14.udp]# bin/gethost www.5iedu.com
     hostname: santaclaus
     addrtype: IPv4
     ip address: 192.168.32.100
     aliases: www.5iedu.com
     ip address: 192.168.32.100
     [root@localhost 14.udp]# bin/gethost localhost    
     hostname: localhost
     addrtype: IPv4
     ip address: 127.0.0.1
     aliases: localhost.localdomain
     aliases: localhost4
     aliases: localhost4.localdomain4
     aliases: localhost.localdomain
     aliases: localhost6
     aliases: localhost6.localdomain6
     ip address: 127.0.0.1
     */
  • 相关阅读:
    oracle之修改/忘记用户密码
    linux 使用错误总结
    oracle数据库之用户管理
    linux命令使用总结
    linux各种压缩包的压缩和解压方法
    logback将日志写入不同文件夹里
    nginx下配置多个web服务
    OKHttp3学习
    linux 发送 post 请求
    maven 项目下 Maven Dependencies 下列表为空
  • 原文地址:https://www.cnblogs.com/5iedu/p/6673274.html
Copyright © 2011-2022 走看看