zoukankan      html  css  js  c++  java
  • 嵌入式开发之函数解析---ip地址2进制转字符inet_ntoa 调用中只生效一次

    inet_addr()

     
      简述:将一个点间隔地址转换成一个in_addr。
      #include <winsock.h>
      unsigned long PASCAL FAR inet_addr( const struct FAR* cp);
      cp:一个以Internet标准“.”间隔的字符串。
      注释:
      本函数解释cp参数中的字符串,这个字符串用Internet的“.”间隔格式表示一个数字的Internet地址。返回值可用作Internet地址。所有Internet地址以网络字节顺序返回(字节从左到右排列)。
      Internet地址用“.”间隔的地址可有下列几种表达方式:
      a.b.c.d,a.b.c,a.b,a
      当四个部分都有定值时,每个都解释成一个字节数据,从左到右组成Internet四字节地址。请注意,当一个Internet地址在Intel机器上表示成一个32位整型数时,则上述的字节为“d.c.b.a”。这是因为Intel处理器的字节是从右向左排列的。
      请注意:只有Berkeley支持下述表达法,Internet其余各处均不支持。考虑到与软件的兼容性,应按规定进行使用。
      对一个三部分地址,最后一部分解释成16位数据并作为网络地址的最右两个字节。这样,三部分地址便很容易表示B组网络地址,如“128.net.host”.
      对一个两部分地址,最后一部分解释成24位数据并作为网络地址的最右三个字节,这样,两部分地址便很容易表示C组网络地址,如“net.host”。
      对仅有一个部分的地址,则将它的值直接存入网络地址不作任何字节的重组。
      返回值:
      若无错误发生,inet_addr()返回一个无符号长整型数,其中以适当字节顺序存放Internet地址。如果传入的字符串不是一个合法的Internet地址,如“a.b.c.d”地址中任一项超过255,那么inet_addr()返回INADDR_NONE。
      参见:

      inet_ntoa().

    inet_addr()函数的实现

    输入是点分的IP地址格式(如A.B.C.D)的字符串,从该字符串中提取出每一部分,转换为ULONG,假设得到4个ULONG型的A,B,C,D,
    ulAddress(ULONG型)是转换后的结果,
    ulAddress = D<<24 + C<<16 + B<<8 + A(网络字节序),即inet_addr(const char *)的返回结果
    另外,我们也可以得到把该IP转换为主机序的结果,转换方法一样
    A<<24 + B<<16 + C<<8 + D

     
     
    inet_ntoa() 
     
    简述:
     
      将网络地址转换成“.”点隔的字符串格式。
     
      #include <winsock.h>
     
      char FAR* PASCAL FAR inet_ntoa( struct in_addr in);
     
      in:一个表示Internet主机地址的结构。
     
      注释:
     
      本函数将一个用in参数所表示的Internet地址结构转换成以“.” 间隔的诸如“a.b.c.d”的字符串形式。请注意inet_ntoa()返回的字符串存放在WINDOWS套接口实现所分配的内存中。应用程序不应假设该内存是如何分配的。在同一个线程的下一个WINDOWS套接口调用前,数据将保证是有效。
     
      返回值:
     
      若无错误发生,inet_ntoa()返回一个字符指针。否则的话,返回NULL。其中的数据应在下一个WINDOWS套接口调用前复制出来。
     
      测试代码如下
     
      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,addr2;
     
      ulong l1,l2;
     
      l1= inet_addr("192.168.0.74");
     
      l2 = inet_addr("211.100.21.179");
     
      memcpy(&addr1, &l1, 4);
     
      memcpy(&addr2, &l2, 4);
     
      printf("%s : %s/n", inet_ntoa(addr1), inet_ntoa(addr2)); //注意这一句的运行结果
     
      printf("%s/n", inet_ntoa(addr1));
     
      printf("%s/n", inet_ntoa(addr2));
     
      return 0;
     
      }
     
      实际运行结果如下:
     
      192.168.0.74 : 192.168.0.74 //从这里可以看出,printf里的inet_ntoa只运行了一次。
     
      192.168.0.74
     
      211.100.21.179
     
      inet_ntoa返回一个char *,而这个char *的空间是在inet_ntoa里面静态分配的,所以inet_ntoa后面的调用会覆盖上一次的调用。第一句printf的结果只能说明在printf里面的可变参数的求值是从右到左的,仅此而已。
     
    inet_aton()
     
    inet_aton是一个改进的方法来将一个字符串IP地址转换为一个32位的网络序列IP地址。这个函数的概要如下:
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    int inet_aton(const char *string, struct in_addr *addr);

    inet_aton函数接受两个参数。参数描述如下:

    1 输入参数string包含ASCII表示的IP地址。
    2 输出参数addr是将要用新的IP地址更新的结构。

    如果这个函数成功,函数的返回值非零。如果输入地址不正确则会返回零。使用这个函数并没有错误码存放在errno中,所以他的值会被忽略。

    对于这个函数有一点迷惑的就是这个函数调用所需要的两个参数。如果我们定义了一个AF_INET套接口地址:

    struct sockaddr_in adr_inet;    /* AF_INET */

    提供给inet_aton函数调用的参数指针为 &adr_inet.sin_addr

    下面这个程序使用inet_aton函数,而不是我们在前面所谈到的in_addr函数。
    /*
     * inetaton.c
     *
     * Example using inet_aton
     */
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <errno.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>

    /*
     * this function reports the error and
     * exits back to the shell
     */
    static void bail(const char *on_what)
    {
        fputs(on_what,stderr);
        fputs("/n",stderr);
    }

    int main(int argc,char **argv)
    {
        int z;
        struct sockaddr_in adr_inet;    /* AF_INET */
        int len_inet;            /* length */
        int sck_inet;            /* Socket */

        /* Create a Socket */
        sck_inet = socket(AF_INET,SOCK_STREAM,0);

        if(sck_inet == -1)
        bail("Socket()");

        /* Establish address */
        memset(&adr_inet,0,sizeof adr_inet);
        adr_inet.sin_family = AF_INET;
        adr_inet.sin_port = htons(9000);

        if( !inet_aton("127.0.0.1",&adr_inet.sin_addr))
        bail("bad address");

        len_inet = sizeof adr_inet;

        /* Bind it to the socket */
        z = bind(sck_inet,(struct sockaddr *)&adr_inet,len_inet);

        if(z == -1)
        bail("bind()");

        /* Display our socket address */
        system("netstat -pa --tcp 2>/dev/null"
            " | grep inetaton");

        return 0;
    }
    程序的运行结果如下:
    S$ ./inetaton
    tcp 0 0 127.0.0.23:9000 *:* CLOSE 1007/inetaton
     
    http://blog.csdn.net/zhangboyj/article/details/6157263
  • 相关阅读:
    topcoder srm 320 div1
    topcoder srm 325 div1
    topcoder srm 330 div1
    topcoder srm 335 div1
    topcoder srm 340 div1
    topcoder srm 300 div1
    topcoder srm 305 div1
    topcoder srm 310 div1
    topcoder srm 315 div1
    如何统计iOS产品不同渠道的下载量?
  • 原文地址:https://www.cnblogs.com/pengkunfan/p/4040190.html
Copyright © 2011-2022 走看看