zoukankan      html  css  js  c++  java
  • 网络编程中常见地址结构与转换(IPv4/IPv6)

    1. sockaddr/sockaddr_in/in_addr (IPv4)、sockaddr6_in/in6_addr/addrinfo (IPv6)

    struct sockaddr { 
          unsigned short sa_family;         /* address family, AF_xxx */ 
          char sa_data[14];                   /* 14 bytes of protocol address */ 
    }; 
       
    struct sockaddr_in { 
          short int sin_family;                /* Address family AF_INET */ 
          unsigned short int sin_port;       /* Port number */ 
          struct in_addr sin_addr;           /* Internet address */ 
          unsigned char sin_zero[8];        /* Same size as struct sockaddr */ 
    };  <br>
    struct in_addr { 
          unsigned long s_addr;             /* Internet address */ 
    }; 
       
    struct sockaddr_in6 { 
          sa_family_t sin6_family;           /* AF_INET6 */ 
          in_port_t sin6_port;                /* transport layer port # */ 
          uint32_t sin6_flowinfo;             /* IPv6 traffic class & flow info */ 
          struct in6_addr sin6_addr;        /* IPv6 address */ 
          uint32_t sin6_scope_id;           /* set of interfaces for a scope */ 
    }; 
    struct in6_addr { 
          uint8_t s6_addr[16];              /* IPv6 address */ 
    }; 
       
    struct addrinfo{ 
          int ai_flags;                         /* AI_PASSIVE,AI_CANONNAME,AI_NUMERICHOST */ 
          int ai_family;                        /* AF_INET,AF_INET6 */ 
          int ai_socktype;                     /* SOCK_STREAM,SOCK_DGRAM */ 
          int ai_protocol;                     /* IPPROTO_IP, IPPROTO_IPV4, IPPROTO_IPV6 */ 
          size_t ai_addrlen;                  /* Length */ 
          char *ai_cannoname;               /* */ 
          struct sockaddr *ai_addr;         /* struct sockaddr */ 
          struct addrinfo *ai_next;          /* pNext */ 

    2. 与IP地址相关的常用网络编程函数

    2.1 地址转化函数

    IPv4中,可使用inet_ntoa/inet_aton来转化字符串形式表示的IPv4地址和数字形式表示的IPv4地址。此两函数不适用于IPv6地址转换。在Linux环境下使用inet_ntoa/inet_atoa时,需加头文件:

    #include<sys/socket.h>
    #include<netinet/in.h>
    #include<arpa/inet.h>

    函数原型:

    int inet_aton(const char * cp,struct in_addr *inp);
    char * inet_ntoa(struct in_addr in);

    举例:

    #include <stdio.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <string.h>
     
    int main(int aargc, char* argv[])
    {
        struct in_addr addr1;
        ulong l1;
        l1 = inet_addr("192.168.0.74");
        memcpy(&addr1, &l1, sizeof(l1));
        printf("%s ", inet_ntoa(addr1));
       if(inet_aton("127.0.0.1", &addr1)){
        printf("inet_aton:ip=%lu ",ntohl(inp.s_addr));
       }
       else{
        printf("inet_aton return -1 when 255.255.255.255 ");
       }
       return 0;
    }

    IPv6中,使用inet_ntop/inet_pton来转化字符串形式表示的IPv6地址和数字形式表示的IPv6地址。IPv4中也可使用这两个函数。

    函数原型:

    int inet_pton(int af, const char *src, void *dst);         <br>//这个函数转换字符串到网络地址,第一个参数af是地址族,转换后存在dst中 af的值可为AF_INET (代表使用IPv4协议)或AF_INET6(代表作用IPv6协议)
     
    const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt);
    //这个函数转换网络二进制结构到ASCII类型的地址,参数的作用和上面相同,只是多了一个参数socklen_t cnt,
    //他是所指向缓存区dst的大小,避免溢出,如果缓存区太小无法存储地址的值,则返回一个空指针,并将errno置为ENOSPC

     举例:

    #include <stdio.h>    
    #include <stdlib.h>    
    #include <string.h>    
    #include <arpa/inet.h>    
               
    int main(int argc, char **argv)    
    {    
        unsigned char buf[sizeof(struct in6_addr)];    
        int domain, s;    
        char str[INET6_ADDRSTRLEN];    
               
        if(argc != 3){    
            fprintf(stderr, "usage: %s {i4|i6|<num>} string/n", argv[0]);    
            exit(EXIT_FAILURE);    
        }    
               
        domain = (strcmp(argv[1], "i4") == 0) ? AF_INET:(strcmp(argv[1], "i6") == 0) ? AF_INET6 : atoi(argv[1]);    
                   
        //IP字符串 ——》网络字节流    
        s = inet_pton(domain, argv[2], buf);    
        if(s<=0){    
            if(0 == s)    
                fprintf(stderr, "Not in presentation format/n");    
            else
                perror("inet_pton");    
            exit(EXIT_FAILURE);    
        }    
               
        //网络字节流 ——》IP字符串    
        if(inet_ntop(domain, buf, str, INET6_ADDRSTRLEN) == NULL){      
            perror("inet ntop/n");    
            exit(EXIT_FAILURE);    
        }    
               
        printf("%s/n", str);    
        exit(EXIT_SUCCESS);    
    }
  • 相关阅读:
    Dynamically allocated memory 动态分配内存【malloc】Memory leaks 内存泄漏
    const pointers
    heap是堆,stack是栈
    Java中使用Cookie
    Postman注册、登录、导出、导入
    HttpServletRequest get post 入参
    判断设置的时间是否大于当前时间
    JS回车登录
    一个普通的Ajax
    Java工具类
  • 原文地址:https://www.cnblogs.com/wuyuxuan/p/10772792.html
Copyright © 2011-2022 走看看