01大小端、网络字节序、地址转换函数的使用

#include <stdio.h>
#include <string.h>

#include <sys/socket.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h> /* superset of previous */
#include <arpa/inet.h>
#include <errno.h>

/*
    man 7 ip
    ipv4套接字地址结构

struct sockaddr_in {
    sa_family_t    sin_family; //address family: AF_INET 
    in_port_t      sin_port;   //port in network byte order
    struct in_addr sin_addr;   //internet address 
    };

 //Internet address
 struct in_addr {
     uint32_t       s_addr;     // address in network byte order 
 };

typedef uint32_t in_addr_t;

struct in_addr {
   in_addr_t s_addr;
};



man htonl
//字节排序函数
#include <arpa/inet.h>

uint32_t htonl(uint32_t hostlong);      //返回网络字节序

uint16_t htons(uint16_t hostshort);     //返回网络字节序

uint32_t ntohl(uint32_t netlong);   //返回主机字节序

uint16_t ntohs(uint16_t netshort);  //返回主机字节序

h代表host;n代表network s代表short;l代表long


*/

//测试大小端
#if 0
void test()
{
    unsigned int data=0x12345678;
    char * p =NULL;
    p= (char *)&data;

    printf("%x, %x, %x, %x \n", p[0], p[1], p[2], p[3]);
    if(p[0] == 0x78)
    {
        printf("当前系统是小端模式\n");  
    }
    else
    {
        printf("当前系统是大端模式\n");  
    }

    printf("把本地字节转换成网络字节\n");

    uint32_t mynetdata = htonl(data);
    p = (char *)&mynetdata;

    if(p[0] == 0x78)
    {
        printf("网络字节序是是小端模式\n");
    }
    else
    {
        printf("网络字节序是是大端模式\n");
    }

}

#endif
/*
    信号处理函数遇上可重入和不可重入函数
    可重入函数概念
    1、为了增强程序的稳定性,在信号处理函数中应使用可重入函数。 
    2、所谓可重入函数是指一个可以被多个任务调用的过程,任务在调用时
      不必担心数据是否会出错。因为进程在收到信号后,就将跳转到信号处理
      函数去接着执行。如果信号处理函数中使用了不可重入函数,那么信号
      处理函数可能会修改原来进程中不应该被修改的数据,这样进程从信号
      处理函数中返回接着执行时,可能会出现不可预料的后果。不可再入函数
      在信号处理函数中被视为不安全函数。
  3、满足下列条件的函数多数是不可重入的:
  (1)使用静态的数据结构,如getlogin(),gmtime(),getgrgid(),getgrnam(),
            getpwuid()以及getpwnam()等等;
  (2)函数实现时,调用了malloc()或者free()函数;
  (3)实现时使用了标准I/O函数的
*/

/*
点分十进制字符串与32位的网络字节序二进制值转换IPV4地址

#include <arpa/inet.h>

            //点分十进制的字符串转化为32位网络字节序
       int inet_aton(const char *cp, struct in_addr *inp);//1

            //点分十进制的字符串转化为32位网络字节序
       in_addr_t inet_addr(const char *cp);//2 已经被废弃,应使用4 最好使用5

            //32位网络字节序转化为点分十进制的字符串
       char *inet_ntoa(struct in_addr in);//4


       in_addr_t inet_network(const char *cp);
       struct in_addr inet_makeaddr(in_addr_t net, in_addr_t host);
       in_addr_t inet_lnaof(struct in_addr in);
       in_addr_t inet_netof(struct in_addr in);



       注意:
       char *inet_ntoa(struct in_addr in);//4

       1)函数返回值指向的字符串驻留在静态内存中,是不可重入的,
       2)函数的参数是一个结构体,而不是指针.
       答案:正常使用应该是传入一个指针,主调函数分配内存,使用完再释放!
       linux内核不这么做,你就分配个内存给到我,我给你转一把,然后把
       内存地址给到你,其实还是你分配的那个内存。
       借用了你分配的内存了。       
*/
//地址转换函数
#if 0
void test()
{                                                                           
        const char *cp = "192.168.66.128";
        struct in_addr inp;
        int ret;
    ret = inet_aton(cp, &inp);//1
        if(ret == 0)
        {
            printf("%s is invalid\n", cp);
        }

        //请你深刻的理解为什么这个地方 要求传入的是元素
        /*
           //Internet address. 
       struct in_addr {
           u_int32_t      s_addr;     // address in network byte order 
       };
       */
     printf("ip is %s\n", inet_ntoa(inp)); 
}

#endif
/*
p代表表达(presentation)  n代表数值(numeric) 
 af  argument  must  be either AF_INET or AF_INET6.
//点分十进制-》32位二进制IPV4或者   
int inet_pton(int af, const char *src, void *dst);

const char *inet_ntop(int af, const void *src,char *dst, socklen_t size);


*/
//地址转换函数

#if 1
void test()
{
    char ip[16] = {0};
    char addptr[16] = {0};
    const char *cp = "192.168.66.128";
    int ret;
    socklen_t size = sizeof(ip);
    char *p = NULL;

    //AF_INET or AF_INET6.
    ret = inet_pton(AF_INET, cp, (void *)addptr);
    if (ret == 0)
    {
        printf("%s is invalid\n", cp);
        return;
    }
    else if (ret == -1)
    {
        if (errno == EAFNOSUPPORT)
            perror("不支持的协议族");
        if (errno == ENOSPC)
            perror("分配的内存不够");
        return;
    }

    if (ip != NULL)
    {
        p = (char *)inet_ntop(AF_INET, addptr, ip, size);
    }
    if (errno == ENOSPC)
    {
        perror("分配的内存size不够");
        return;
    }
    if (p != ip)
    {
        perror("inet_ntop");
        return;
    }
    printf("ip is %s\n", ip);
}

#endif

int main()
{
    test();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值