• inet_addr() inet_ntoa() inet_pton inet_ntop sockaddr_in


    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()

      简述:
    将网络地址转换成“.”点隔的字符串格式。
    #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 ", inet_ntoa(addr1), inet_ntoa(addr2)); //注意这一句的运行结果
    printf("%s ", inet_ntoa(addr1));
    printf("%s ", 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里面的可变参数的求值是从右到左的,仅此而已。

    sockaddr sockaddr_in
    struct sockaddr {
    unsigned short sa_family;    
    char sa_data[14];                
    };
    sa_family是地址家族,一般都是“AF_xxx”的形式。好像通常大多用的是都是AF_INET。
    sa_data是14字节协议地址。
    此数据结构用做bind、connect、recvfrom、sendto等函数的参数,指明地址信息。

    但一般编程中并不直接针对此数据结构操作,而是使用另一个与sockaddr等价的数据结构
    sockaddr_in(在netinet/in.h中定义):
    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 {
    unsigned long s_addr;
    };

    typedef struct in_addr {
    union {
                struct{
                            unsigned char s_b1,
                            s_b2,
                            s_b3,
                            s_b4;
                            } S_un_b;
               struct {
                            unsigned short s_w1,
                            s_w2;
                            } S_un_w;
                unsigned long S_addr;
              } S_un;
    } IN_ADDR;

    sin_family指代协议族,在socket编程中只能是AF_INET
    sin_port存储端口号(使用网络字节顺序)
    sin_addr存储IP地址,使用in_addr这个数据结构
    sin_zero是为了让sockaddr与sockaddr_in两个数据结构保持大小相同而保留的空字节。
    s_addr按照网络字节顺序存储IP地址

    sockaddr_in和sockaddr是并列的结构,指向sockaddr_in的结构体的指针也可以指向
    sockadd的结构体,并代替它。也就是说,你可以使用sockaddr_in建立你所需要的信息,
    在最后用进行类型转换就可以了bzero((char*)&mysock,sizeof(mysock));//初始化
    mysock结构体名
    mysock.sa_family=AF_INET;
    mysock.sin_addr.s_addr=inet_addr("192.168.0.1");
    ……
    等到要做转换的时候用:
    (struct sockaddr*)mysock 




    inet_pton和inet_ntop函数

    Linux下这2个IP地址转换函数,可以在将IP地址在“点分十进制”和“整数”之间转换
    而且,inet_pton和inet_ntop这2个函数能够处理ipv4和ipv6。算是比较新的函数了。

    inet_pton函数原型如下[将“点分十进制” -> “整数”]
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    int inet_pton(int af, const char *src, void *dst);
    这个函数转换字符串到网络地址,第一个参数af是地址族,转换后存在dst中
    inet_pton 是inet_addr的扩展,支持的多地址族有下列:

    af = AF_INET
     src为指向字符型的地址,即ASCII的地址的首地址(ddd.ddd.ddd.ddd格式的),函数将该地址
     转换为in_addr的结构体,并复制在*dst中
    af =AF_INET6
     src为指向IPV6的地址,,函数将该地址
     转换为in6_addr的结构体,并复制在*dst中
    如果函数出错将返回一个负值,并将errno设置为EAFNOSUPPORT,如果参数af指定的地址族和src格式不对,函数将返回0。

    inet_ntop函数原型如下[将“点分十进制” -> “整数”]
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt);
    这个函数转换网络二进制结构到ASCII类型的地址,参数的作用和上面相同,只是多了一个参数socklen_t cnt,他是所指向缓存区dst的大小,避免溢出,如果缓存区太小无法存储地址的值,则返回一个空指针,并将errno置为ENOSPC

    下面是例程

    char IPdotdec[20]; //存放点分十进制IP地址
    struct in_addr s; // IPv4地址结构体

    int main (void)
    {
     // 输入IP地址
     printf("Please input IP address: ");
     scanf("%s", &IPdotdec);
     // 转换
     inet_pton(AF_INET, IPdotdec, (void *)&s);
     printf("inet_pton: 0x%x ", s.s_addr); // 注意得到的字节序
     // 反转换
     inet_ntop(AF_INET, (void *)&s, IPdotdec, 16);
     printf("inet_ntop: %s ", IPdotdec);
     
    }

  • 相关阅读:
    HDOJ_ACM_统计问题
    HDOJ_ACM_Queuing
    HDOJ_ACM_数塔
    HDOJ_ACM_免费馅饼
    HDOJ_ACM_FatMouse's Speed
    HDOJ_ACM_Monkey and Banana
    斐波南希数列
    .net framework 2.0的WinForm的ShowInTaskBar属性的bug
    寂寞的季节
    广告一下
  • 原文地址:https://www.cnblogs.com/sdgwc/p/3239804.html
Copyright © 2020-2023  润新知