zoukankan      html  css  js  c++  java
  • [原]socket通信实现域名解析

    //extern     unsigned char gSntpServerIP[20];
    int GetNTPTime(unsigned char *ntpServerIP,unsigned int ntpPort,unsigned int  *data)  
    {  
        int sockfd=0;  
        char ntpServerName[20];
        
          
        STNP_Header H_NTP;        
        
        H_NTP.LiVnMode = 0x1b;//LI(2bit )  VN(3bit 版本)      Mode(3bit客户端模式)  
        H_NTP.Stratum = STRATUM;
        H_NTP.Poll = POLL;
        H_NTP.Precision =PREC;
        
        memset(ntpServerName,0,sizeof(ntpServerName));
        sprintf(ntpServerName,"%s",ntpServerIP);
    
        NF_LOG(DEBUG_K,"@_@,sync time from %s,H_NTP.Stratum=%d
    ", ntpServerName,H_NTP.Stratum); 
    
        #if 0//不能解析域名的方式
        struct sockaddr_in server;
        server.sin_family = AF_INET;  
        server.sin_addr.s_addr = gethostIPbyname((const char*)ntpServerName);  
        server.sin_port = htons(ntpPort);
        if(-1 == (int)server.sin_addr.s_addr)  
        {
            NF_LOG(ERROR_L,"[%s,%d]s_addr error...
    ",__FUNCTION__,__LINE__);
            return -1;  
        }
        
        sockfd = socket(AF_INET, SOCK_DGRAM, 0);  
        if(sockfd<0)  
        {  
            NF_LOG(ERROR_L,"[%s,%d]socket error...
    ",__FUNCTION__,__LINE__);
            return -1;  
        }
        #endif
    
        
        #if 1//getaddrinfo可以解析域名的方式
        int  rc;
        addrinfo hints, *res = NULL,*cur=NULL;
        memset(&hints, 0, sizeof(hints));
        hints.ai_family = AF_UNSPEC;
        hints.ai_socktype = SOCK_DGRAM;
        hints.ai_protocol = IPPROTO_UDP;
        char port[10];
        memset(port,0,sizeof(port));
        sprintf(port,"%d",ntpPort);
        rc = getaddrinfo((const char*)ntpServerName, port, &hints, &res);
    
        if (rc != 0) 
        {
            NF_LOG(ERROR_L,"[%s,%d]getaddrinfo error...rc=%s
    ",__FUNCTION__,__LINE__,gai_strerror(rc));
            
            return -1;  
        }
    
        struct sockaddr_in *addr;
        char m_ipaddr[16];
        memset(m_ipaddr,0,sizeof(m_ipaddr));
        
         for (cur = res; cur != NULL; cur = cur->ai_next) {
            addr = (struct sockaddr_in *)cur->ai_addr;
            inet_pton(AF_INET, m_ipaddr, (void *)addr);
            inet_ntop(AF_INET, (void *)&addr, m_ipaddr, 16);// 反转换
            printf("@_@:Parse ip:%s
    ",m_ipaddr);
        }
        
        sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
        if (sockfd < 0) 
        {
            NF_LOG(ERROR_L,"[%s,%d]socket error...
    ",__FUNCTION__,__LINE__);
            return -1;  
        }
        #endif
    
        //if(sendto(sockfd, (void*)&H_NTP, sizeof(STNP_Header), 0, (struct sockaddr*)&server, sizeof(server))<0)  
        if(sendto(sockfd, (void*)&H_NTP, sizeof(STNP_Header), 0, res->ai_addr, res->ai_addrlen)<0)  
        {  
            NF_LOG(ERROR_L,"[%s,%d]sendto error...
    ",__FUNCTION__,__LINE__); 
            return -1;  
        }  
          
        fd_set r;  
        FD_ZERO(&r);  
        FD_SET(sockfd, &r);  
        struct timeval timeout;  
        timeout.tv_sec = 10;  
        timeout.tv_usec = 0;  
          
        if(1 != select(sockfd+1, &r, NULL, NULL, &timeout))  
        {
            NF_LOG(ERROR_L,"[%s,%d] select error...
    ",__FUNCTION__,__LINE__);
            return -1;  
        }
        
        if(recv(sockfd, (void*)data, 48, 0)<0) //48 后续要定义成宏
        {
            NF_LOG(ERROR_L,"[%s,%d]recv error...
    ",__FUNCTION__,__LINE__);
            return -1;  
        }
        
        close(sockfd);  
        return 0;  
    }  
    getaddrinfo函数

    使用到的结构体理解
    addrinfo
    sockaddr_in
    /* Internet address.  */

    typedef __u16 in_port_t;
    typedef __u32 in_addr_t;

    struct in_addr
      {
        in_addr_t s_addr;
      };
    
    
    
    /* Structure describing an Internet socket address.  */
    struct sockaddr_in
      {
        __SOCKADDR_COMMON (sin_);
        in_port_t sin_port;            /* Port number.  */
        struct in_addr sin_addr;        /* Internet address.  */
    
        /* Pad to size of `struct sockaddr'.  */
        unsigned char sin_zero[sizeof (struct sockaddr) -
                   __SOCKADDR_COMMON_SIZE -
                   sizeof (in_port_t) -
                   sizeof (struct in_addr)];
      };
    将sockaddr_in格式的地址,打印成点分十进制的方式:
    
    

      struct sockaddr_in *addr;
      char m_ipaddr[16];
      memset(m_ipaddr,0,sizeof(m_ipaddr));


    for
    (cur = res; cur != NULL; cur = cur->ai_next) { addr = (struct sockaddr_in *)cur->ai_addr; inet_pton(AF_INET, m_ipaddr, (void *)addr); inet_ntop(AF_INET, (void *)&addr, m_ipaddr, 16);// 反转换 printf("@_@:Parse ip:%s ",m_ipaddr); }

    ======

    需要区分下这些结构体的差异

    sockaddr_in 用于IPV4的网络Internet IP/port,所以其结构成员sin_family必须填入AF_INET??

    struct sockaddr_in server;
        server.sin_family = AF_INET;  
        server.sin_addr.s_addr = gethostIPbyname((const char*)ntpServerName);  
        server.sin_port = htons(ntpPort);
        if(-1 == (int)server.sin_addr.s_addr)  
        {
            NF_LOG(ERROR_L,"[%s,%d]s_addr error...
    ",__FUNCTION__,__LINE__);
            return -1;  
        }

       addrinfo  

    addrinfo hints, *res = NULL,*cur=NULL;
        memset(&hints, 0, sizeof(hints));
        hints.ai_family = AF_UNSPEC;
        hints.ai_socktype = SOCK_DGRAM;
        hints.ai_protocol = IPPROTO_UDP;
        char port[10];
        memset(port,0,sizeof(port));
        sprintf(port,"%d",ntpPort);
        rc = getaddrinfo((const char*)ntpServerName, port, &hints, &res);

    根据地址域获取到的信息存放在res

    操作res获取的地址和port信息来链接及发送数据:
    sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
        if (sockfd < 0) 
        {
            NF_LOG(ERROR_L,"[%s,%d]socket error...
    ",__FUNCTION__,__LINE__);
            return -1;  
        }
    
    if(sendto(sockfd, (void*)&H_NTP, sizeof(NTP_Header), 0, res->ai_addr, res->ai_addrlen)<0)  
        {  
            NF_LOG(ERROR_L,"[%s,%d]sendto error...
    ",__FUNCTION__,__LINE__); 
            return -1;  
        } 

     getaddrinfo能够获取多个ip地址,这里可以去bind尝试看看哪个可以通来优化:

    https://blog.csdn.net/an_zhenwei/article/details/8591729
    待确认:
    gethostIPbyname 不能解析地址域吗???当时之所以不能解析的原因是由于没有添加DNS服务器在resolv.conf






  • 相关阅读:
    python 图片验证码降噪
    python 视频配音、剪辑
    Python实现音乐的剪辑
    OpenCV-Python 视频读取
    OpenCV-Python 人脸眼睛嘴识别
    OpenCV-Python 人脸识别
    numpy
    python学习笔记(3)---cookie & session
    python爬虫学习笔记(2)-----代理模式
    python爬虫学习笔记(1)
  • 原文地址:https://www.cnblogs.com/secondtononewe/p/9818184.html
Copyright © 2011-2022 走看看