网络编程之inet_pton函数

Posted 老樊Lu码

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络编程之inet_pton函数相关的知识,希望对你有一定的参考价值。

    这个函数的功能:将IP地址从字符串格式转换成网络地址格式,支持Ipv4和Ipv6.

函数原型: static int inet_pton(int af, const char *src,void *dst)

af: address family(协议族),支持的协议族有下面几种:

AF_INET Inetnet的Ipv4协议

AF_INET Inetnet的Ipv6协议

src:是个指针,指向保存IP地址字符串形式的字符串。

dst:指向存放网络地址的结构体的首地址

int inet_pton(af, src, dst) 
{

    int af; 
    const char *src; 
    void *dst;  

    switch (af) { 
    case AF_INET: 
        return (inet_pton4(src, dst)); 
    case AF_INET6: 
        return (inet_pton6(src, dst)); 
    default: 
        __set_errno (EAFNOSUPPORT); 
        return (-1); 
    } 
    /* NOTREACHED */ 
}

       这部分代码就是通过af这个参数来判断你输入的是Ipv4还是Ipv6,然后调用对应的转换函数inet_pton4(src, dst)和inet_pton6(src, dst)。

假设src = ”192.168.0.1”

static int internal_function inet_pton4(src, dst)

const char *src;

     u_char *dst;/*类型的强制转换,这边声明dst为unsigned char 类型是为了下面的转换做准备的,因为Ip地址的每一位都是在0-255之间,所以没有必要占用更多的空间,也为下面的输出提供了便利*/

int saw_digit, octets, ch;

u_char tmp[NS_INADDRSZ], *tp;/*tmp是用来存放转换过后的数字的,NS_INADDRSZ是个宏定义,这里值是4,表示Ipv4地址的长度是4个字节,每个字节存放的是一个整数,如上例转换过后tmp={192,168,0,1};fp是指向tmp的,下面就可以看到。*/

saw_digit = 0;/*是否还是处理同一个整数中的不同位*/

octets = 0;/*表示已处理整数的个数*/

*(tp = tmp) = 0;/*这句话是对tp和tmp进行初始化,使tp=tmp,同时使tmp初始化成一个空字符串。*/

while ((ch = *src++) != '\\0') {/*这个开始对输入字符串每个字符进行检测,看是否到达终点,如果没有到达终点,就对这个字符进行下面的操作*/

if (ch >= '0' && ch <= '9') { 
            u_int new = *tp * 10 + (ch - '0');
            if (saw_digit && *tp == 0) 
                return (0); 
            if (new > 255) 
                return (0); 
            *tp = new; 
            if (! saw_digit) { 
                if (++octets > 4) 
                    return (0); 
                saw_digit = 1; 
            } 
        }

     上面一段代码主要是对数字字符串进行处理,如果这个字符是数字字符的话,就要将其转化成整数数字,同时根据saw_digit的值来判断前一个被处理的字符是否是数字字符,从而达到统计已转换的数字的个数,一个数字可以由多个字符数字构成,(如192,就是有3个字符构成),若一个数字有没有转换结束,则saw_digit=1;则octerts则不会继续进自增运算。

  else if (ch == '.' && saw_digit) { 
        if (octets == 4) 
            return (0); 
        *++tp = 0; 
        saw_digit = 0; 
    } else 
        return (0); 
}

     上面一段代码主要是判断字符是否是”.”分隔符,如果是点分隔符,则表示新的一个整数的转换将要开始,就将saw_digit = 0;从而达到开始新的整数转换的目的。

   if (octets < 4) 
         return (0);
     memcpy(dst, tmp, NS_INADDRSZ); 
        return (1); 
}

      这段代码没有什么难理解的地方主要就是如果转换出来的整数的个数大于四,则出错,返回0.

     代码赏析:这个代码对边界情况考虑的非常严密,对每个可能出现的问题都做了防范。最主要的是充分利用unsigned char型的优点,节省了空间方便了输出。

如果你想输出最后的结果,也就是转换过后的网络地址格式的数据,也很简单。直接:

for(i=0;i<4;i++) printf(“%d ”,(int)dst[i]);

以上是关于网络编程之inet_pton函数的主要内容,如果未能解决你的问题,请参考以下文章

UNIX网络编程中的字节序问题

为啥地址信息没有用 gethostbyname 和 inet_pton 函数正确存储?

面向面试编程代码片段之GC

前端面试题之手写promise

Python之如何优雅的重试

我的Android进阶之旅NDK开发之在C++代码中使用Android Log打印日志,打印出C++的函数耗时以及代码片段耗时详情