• my_net_pton


    inet_pton的作用是将可读的IP地址(ipv4和ipv6均支持)字符串转换成网络序的函数

    main.cpp

    #include <Windows.h>
    #include <iostream>
    
    #include "my_net_pton.h"
    using namespace std;
    
    int main() {
        cout << "hello" << endl;
    
        int lRet = 0;
        UINT32 remote_address;
        lRet = my_pton(2, "192.168.6.38", &remote_address);
        cout << "remote_address:" << remote_address;
        lRet = my_pton(2, "193.168.6.38", &remote_address);
        cout << "remote_address:" << remote_address;
    
        return 0;
    }
    

      my_net_pton.h

    #ifndef MY_NET_PTON_H
    #define MY_NET_PTON_H
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    #define NS_INT16SZ   2
    #define NS_INADDRSZ      4
    #define NS_IN6ADDRSZ    16
    
    	int my_pton(int af, const char* src, void* dst);
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif
    

      my_net_pton.c

    #include <ntdef.h>
    #include <inaddr.h>
    #include <in6addr.h>
    #include "my_net_pton.h"
    #include <common/my_wsa.h>
    
    // ipv4是4个字节,xxx.yyy.mmm.nnn
    // 注意:每个八位组第一个不能为0
    // 每个八位组值不能大于255
    // 只能有4个八位组
    // 整个ip字符串中只能有数字和'.'符号
    // dst的结构体不需要理会,只需要知道dst为接收内存且长度只能是4字节,其他随意
    static int inet_pton4(const char *src, const char *end, unsigned char *dst)
    {
        int saw_digit; // 每个八位组是否遇到数字标记,新的八位组将会清除标记
        int octets;     // 八位组的个数,ip地址合法,则为4个
        int ch;         // 遍历字符串,每次获得的字符
        // NS_INADDRSZ长度是4个字节, 宏定义在nameser.h中
        // 注意tmp不是字符串,仅仅是用来存放4个字节的数据,无'\0'
        unsigned char tmp[NS_INADDRSZ];
        unsigned char *tp;      // tp指的是八位组
        
        saw_digit = 0;
        octets = 0;
        *(tp = tmp) = 0; // *tp = 0;初始化必须为0,计算数值的时候会有依赖
        
        // 本函数实际上是转换成网络序的,所以方向是src -> end
        // 如果仅仅转换成二进制,方向是end -> src
        while (src < end)
        {
            ch = *src++; // 得到获得的ASCII值,src指向下一个字符
            if (ch >= '0' && ch <= '9')
            {
                // 八位组迭代,比如192.168.8.217
                // 以192为例:
                // 0 -> 0 * 10 + 1 = 1 -> 1 * 10 + 9 = 19 -> 19 * 10 + 2 = 192
                // 在将192赋值到tmp的第一个字节上(第一个八位组)
                unsigned int new = *tp * 10 + (ch - '0');
                
                // 八位组中不能以0开头,比如192.168.08.217是错误的
                if (saw_digit && *tp == 0)
                    return 0;
                // 某一个八位组值不能超过255
                if (new > 255)
                    return 0;
                
                // 八位组赋值
                *tp = (unsigned char)new;
                
                // 一般是在遇到'.'的时候,(! saw_digit)为0
                // 而在'.'之后的第一个数字置为1
                // 统计八位组的数目,由于在运行中,所以值不得超过4
                if (! saw_digit)
                {
                    if (++octets > 4)
                        return 0;
                    saw_digit = 1;
                }
            }
            else if (ch == '.' && saw_digit)
            {
                if (octets == 4)
                    return 0;
                
                // 下一个八位组赋值,必须为0,方面迭代
                // saw_digit标记为未遇到数值
                *++tp = 0;
                saw_digit = 0;
            }
            else
                return 0; // 其他字符,直接返回错误
        }
        if (octets < 4)
            return 0;
        memcpy (dst, tmp, NS_INADDRSZ);
        return 1;
    }
     
    static int hex_digit_value(char ch)
    {
        if ('0' <= ch && ch <= '9')
            return ch - '0';
        if ('a' <= ch && ch <= 'f')
            return ch - 'a' + 10;
        if ('A' <= ch && ch <= 'F')
            return ch - 'A' + 10;
        return -1;
    }
     
    static int inet_pton6(const char *src, const char *src_endp, unsigned char *dst)
    {
        unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
        const char *curtok;
        int ch;
        size_t xdigits_seen;    /* Number of hex digits since colon.  */
        unsigned int val;
        
        tp = memset (tmp, '\0', NS_IN6ADDRSZ);
        endp = tp + NS_IN6ADDRSZ;
        colonp = NULL;
        
        /* Leading :: requires some special handling.  */
        if (src == src_endp)
            return 0;
        if (*src == ':')
        {
            ++src;
            if (src == src_endp || *src != ':')
                return 0;
        }
        
        curtok = src;
        xdigits_seen = 0;
        val = 0;
        while (src < src_endp)
        {
            ch = *src++;
            int digit = hex_digit_value ((char)ch);
            if (digit >= 0)
            {
                if (xdigits_seen == 4)
                    return 0;
                val <<= 4;
                val |= digit;
                if (val > 0xffff)
                    return 0;
                ++xdigits_seen;
                continue;
            }
            if (ch == ':')
            {
                curtok = src;
                if (xdigits_seen == 0)
                {
                    if (colonp)
                        return 0;
                    colonp = tp;
                    continue;
                }
                else if (src == src_endp)
                    return 0;
                if (tp + NS_INT16SZ > endp)
                    return 0;
                *tp++ = (unsigned char) (val >> 8) & 0xff;
                *tp++ = (unsigned char) val & 0xff;
                xdigits_seen = 0;
                val = 0;
                continue;
            }
            if (ch == '.' && ((tp + NS_INADDRSZ) <= endp)
                && inet_pton4 (curtok, src_endp, tp) > 0)
            {
                tp += NS_INADDRSZ;
                xdigits_seen = 0;
                break;  /* '\0' was seen by inet_pton4.  */
            }
            return 0;
        }
        if (xdigits_seen > 0)
        {
            if (tp + NS_INT16SZ > endp)
                return 0;
            *tp++ = (unsigned char) (val >> 8) & 0xff;
            *tp++ = (unsigned char) val & 0xff;
        }
        if (colonp != NULL)
        {
            /* Replace :: with zeros.  */
            if (tp == endp)
            /* :: would expand to a zero-width field.  */
                return 0;
            size_t n = tp - colonp;
            memmove (endp - n, colonp, n);
            memset (colonp, 0, endp - n - colonp);
            tp = endp;
        }
        if (tp != endp)
            return 0;
        memcpy (dst, tmp, NS_IN6ADDRSZ);
        return 1;
    }
     
    static int _inet_pton_length(int af, const char *src, size_t srclen, void *dst)
    {
        switch (af)
        {
            case AF_INET:
                return inet_pton4(src, src + srclen, dst);
            case AF_INET6:
                return inet_pton6(src, src + srclen, dst);
            default:
                //printf("invalid AF, af: %d.\n", af);
                return -1;
        }
        return -1;
    }
     
    int my_pton(int af, const char *src, void *dst)
    {
        return _inet_pton_length(af, src, strlen(src), dst);
    }
     
     
    //void AddrConvertTest(void)
    //{
    //    char szIpv4[INET_ADDRSTRLEN] = "192.168.8.217";
    //    //char szIpv4[INET_ADDRSTRLEN] = "192.168.10.1";
    //    unsigned int ulIpv4 = 3232237785;
    //    printf("ip: %s, dec: %u, little-endian-hex: %#x, big-endian-hex: %#x\n", szIpv4, ulIpv4, ulIpv4, htonl(ulIpv4));
    //    
    //    struct in_addr stIpv4Addr = {0};
    //    int lRet = 0;
    //    lRet = pton(AF_INET, szIpv4, &stIpv4Addr);
    //    printf("pton ret: %d, ip: %s, s_addr: %#x.\n", lRet, szIpv4, stIpv4Addr.s_addr);
    //    return;
    //}
     
    //void AddrConvertLibcTest(void)
    //{
    //    char szStrIp[] = "192.168.8.217";
    //    unsigned int ulIp = 3232237785;
    //    printf("ip: %s, dec: %u, little-endian-hex: %#x, big-endian-hex: %#x\n", szStrIp, ulIp, ulIp, htonl(ulIp));
    //    char *pcTmp = NULL;
    //    int lRet = 0;
    //    struct in_addr stInAddr = {0};
    //    stInAddr.s_addr = inet_addr("192.168.8.217");
    //    pcTmp = inet_ntoa(stInAddr);
    //    printf("inet_ntoa, ret: %s, s_addr: %#x.\n", pcTmp, stInAddr.s_addr);
    //    
    //    /** inet_addr 处理255.255.255.255以及错误的ip返回的结果为0xffffffff
    //     */
    //    stInAddr.s_addr = inet_addr("259.255.255.255");
    //    printf("inet_addr s_addr: %#x.\n", stInAddr.s_addr);
    //    
    //    char szIp[INET_ADDRSTRLEN] = "192.168.8.217";
    //    struct in_addr stOutAddr = {0};
    //    lRet = inet_aton(szIp, &stOutAddr);
    //    printf("inet_aton ret: %d, ip: %s, s_addr: %#x.\n", lRet, szIp, stOutAddr.s_addr);
    //    
    //    struct in_addr stAddr2 = {0};
    //    char szIp2[INET_ADDRSTRLEN] = "192.168.8.217";
    //    // 文本字符串格式转换成网络字节序的二进制地址
    //    lRet = inet_pton(AF_INET, szIp2, &stAddr2);
    //    int ipv4StructSize = sizeof(struct in_addr);
    //    printf("inet_pton ret: %d, ip: %s, s_addr: %#x.\n", lRet, szIp2, stAddr2.s_addr);
    //    
    //    const char *pcTmp2 = NULL;
    //    memset(szIp2, 0, sizeof(szIp2));
    //    // 网络字节序的二进制地址转换成文本字符串格式
    //    pcTmp2 = inet_ntop(AF_INET, &stAddr2, szIp2, INET_ADDRSTRLEN);
    //    printf("inet_ntop ret: %s, ip: %s.\n", pcTmp2, szIp2);
    //}
    

      

  • 相关阅读:
    5.3Role和Claims授权「深入浅出ASP.NET Core系列」
    【干货分享】可能是东半球最全的.NET Core跨平台微服务学习资源
    5.2基于JWT的令牌生成和定制「深入浅出ASP.NET Core系列」
    5.1基于JWT的认证和授权「深入浅出ASP.NET Core系列」
    4.5管道实现机制和模拟构建管道「深入浅出ASP.NET Core系列」
    4.4管道和中间件介绍「深入浅出ASP.NET Core系列」
    目录导航「深入浅出ASP.NET Core系列」
    4.3dotnet watch run「深入浅出ASP.NET Core系列」
    4.2WebHost配置「深入浅出ASP.NET Core系列」
    4.1ASP.NET Core请求过程「深入浅出ASP.NET Core系列」
  • 原文地址:https://www.cnblogs.com/chunyou128/p/16341802.html
Copyright © 2020-2023  润新知