zoukankan      html  css  js  c++  java
  • 【VS开发】IP地址格式转换(htonl、ntohl;inet_addr、inet_ntoa)

    1、htonl ()和ntohl( )

    u_long PASCAL FAR ntohl (u_long netlong);

    u_short PASCAL FAR ntohs (u_short netshort);

    ntohl( )-----网络顺序转换成主机顺序

    u_long PASCAL FAR htonl (u_long hostlong);

    u_short PASCAL FAR htons (u_short hostshort);

    htonl ()-----主机顺序转换成网络顺序

    2、inet_addr( )和inet_ntoa ( )

    unsigned long PASCAL FAR inet_addr (const char FAR * cp);

    char FAR * PASCAL FAR inet_ntoa (struct in_addr in);

    inet_addr函数需要一个字符串作为其参数,该字符串指定了以点分十进制格式表示的IP地址(例如:192.168.0.16)。而且inet_addr函数会返回一个适合分配给S_addr的u_long类型的数值。

    Inet_ntoa函数会完成相反的转换,它接受一个in_addr结构体类型的参数并返回一个以点分十进制格式表示的IP地址字符串。

    sockaddr_in , sockaddr , in_addr区别

    struct   sockaddr   {  
                    unsigned   short   sa_family;     
                    char   sa_data[14];     
            };  
      上面是通用的socket地址,具体到Internet   socket,用下面的结构,二者可以进行类型转换  
             
      struct   sockaddr_in   {  
                    short   int   sin_family;     
                    unsigned   short   int   sin_port;     
                    struct   in_addr   sin_addr;     
                    unsigned   char   sin_zero[8];     
            };  
            struct   in_addr就是32位IP地址。  
            struct   in_addr   {  
                    union {
                            struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;
                            struct { u_short s_w1,s_w2; } S_un_w;
                            u_long S_addr; 
                    } S_un;

                    #define s_addr  S_un.S_addr
            };  
       inet_addr()是将一个点分制的IP地址(如192.168.0.1)转换为上述结构中需要的32位IP地址(0xC0A80001)。

    填值的时候使用sockaddr_in结构,而作为函数(如socket, listen, bind等)的参数传入的时候转换成sockaddr结构就行了,毕竟都是16个字符长。

    通常的用法是:  
      int   sockfd;  
      struct   sockaddr_in   my_addr;  
      sockfd   =   socket(AF_INET,   SOCK_STREAM,   0);     
       
      my_addr.sin_family   =   AF_INET;     
      my_addr.sin_port   =   htons(MYPORT);     
      my_addr.sin_addr.s_addr   =   inet_addr("192.168.0.1");  
       
      bzero(&(my_addr.sin_zero),   8);     
        
      bind(sockfd,   (struct   sockaddr   *)&my_addr,   sizeof(struct   sockaddr));

    可以用C++做个不太准确的假设。  
    sockaddr是base   class    
    sockaddr_in   等是derived   class  
    如此一来,bind,   connect   ,   sendto   ,   recvfrom等函数就可以使用base   class  
    来处理多种不同的derived   class了。  
    但是实际上,这是没有继承关系数据结构(C嘛),所以需要强制造型来转换数据类型。正因为如此,在sendto的时候需要给出len长度,因为不同的sockaddr_xx实现长度并不相同。

    名词解析:

    主机字节序:

    不同的CPU有不同的字节序类型,这些字节序是指整数在内存中保存的顺序,这个叫做主机序。最常见的有两种 1.Little endian:低字节存高地址,高字节存低地址 2.Big endian:低字节存低地址,高字节存高地址

    网络字节序:

    网络字节顺序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释。网络字节顺序采用big endian排序方式。

    为了进行转换bsd socket提供了转换的函数,有下面四个网络与主机字节转换函数:htons ntohs htonl ntohl (s 就是short l是long h是host n是network)

    htons 把unsigned short类型从主机序转换到网络序,htonl 把unsigned long类型从主机序转换到网络序,ntohs 把unsigned short类型从网络序转换到主机序,ntohl 把unsigned long类型从网络序转换到主机序。

    在使用little endian的系统中 这些函数会把字节序进行转换 在使用big endian类型的系统中这些函数会定义成空宏

    将用点分割的IP地址转换位一个in_addr结构的地址,这个结构的定义见笔记(一),实际上就是一个unsigned long值。计算机内部处理IP地址可是不认识如192.1.8.84之类的数据。  
    unsigned long inet_addr( const char FAR * cp );
    举例:inet_addr("192.1.8.84")=1409810880
    inet_addr("127.0.0.1")= 16777343

    如果发生错误,函数返回INADDR_NONE值。
    将网络地址转换位用点分割的IP地址,是上面函数的逆函数。  
    char FAR * inet_ntoa( struct in_addr in );
    举例:char * ipaddr=NULL;
    char addr[20];
    in_addr inaddr;
    inaddr. s_addr=16777343;
    ipaddr= inet_ntoa(inaddr);
    strcpy(addr,ipaddr);  
    这样addr的值就变为127.0.0.1。
    注意意不要修改返回值或者进行释放动作。如果函数失败就会返回NULL值

  • 相关阅读:
    sencha touch 扩展篇之将sencha touch打包成安装程序(上)- 使用sencha cmd打包安装程序
    sencha touch 扩展篇之使用sass自定义主题样式 (下)通过css修改官方组件样式以及自定义图标
    一个不错的android组件的网站
    sencha touch 扩展篇之使用sass自定义主题样式 (上)使用官方的api修改主题样式
    sencha touch 入门系列 (九) sencha touch 布局layout
    面试题总结
    国外接活网站Elance, Freelancer和ScriptLance的介绍和对比
    sencha touch 入门系列 扩展篇之sencha touch 项目打包压缩
    Android Design Support Library——Navigation View
    设计模式——命令模式
  • 原文地址:https://www.cnblogs.com/huty/p/8517274.html
Copyright © 2011-2022 走看看