• 【Linux】C语言之IP地址转换方法


    项目中遇到很多种类型主机序和网络序互转的情况,通过下面样例,对不同的情况进行代码实现。本文只介绍转换方法,不介绍网络序和主机序的区别。

    情景一:网络字节序转主机序

    解析处理网络数据报文时,经常遇到将解析出的IP地址或者PORT等信息保存下来,此时部分需求是保存为主机序列,部分要求为网络序(进行二次匹配查询时不必再次转换)

    无符号整型数字网络序转主机序代码如下:

    #include <stdio.h>
    #include <arpa/inet.h>
    
    #define NET_NUM 123
    
    int main(void)
    {
        // 1字节数字转换(不用转换)
        uint8_t num0 = NET_NUM;
        printf("num0 = %u\n", num0);
        
        // 2字节数字转换
        uint16_t num1 = ntohs(NET_NUM);
        printf("num1 = %u\n", num1);
        
        // 4字节数字转换
    	uint32_t num2 = ntohl(NET_NUM);
    	printf("num2 = %u\n", num2);
        
        // 8字节数字转换
        uint64_t num3 = be64toh(NET_NUM);
        printf("num3 = %lu\n", num3);
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    情景二:主机序转网络字节序

    有时候通过socket发送数据时,需要先将数据格式化为网络字节序,因此会用到。

    无符号整型数字主机序转网络序代码如下:

    #include <stdio.h>
    #include <arpa/inet.h>
    
    #define HOST_NUM 123
    
    int main(void)
    {
        // 1字节数字转换(不用转换)
        uint8_t num0 = HOST_NUM;
        printf("num0 = %u\n", num0);
        
        // 2字节数字转换
        uint16_t num1 = htons(HOST_NUM);
        printf("num1 = %u\n", num1);
        
        // 4字节数字转换
    	uint32_t num2 = htonl(HOST_NUM);
    	printf("num2 = %u\n", num2);
        
        // 8字节数字转换
        uint64_t num3 = htobe64(HOST_NUM);
        printf("num3 = %lu\n", num3);
    
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    情景三:IP地址互相之间的转换

    IPV4占用大小为4字节,IPV6占用大小为16字节,IP地址互相转换代码如下:

    #include <stdio.h>
    #include <arpa/inet.h>
    
    // IPv4
    static void ipv4_tp(char *Ipv4){
        uint32_t net_ipv4, host_ipv4;
        char strIpv4[16] = {0};
        // 点分十制转网络序
        inet_pton(AF_INET, Ipv4, &net_ipv4);
        printf("net_ipv4 	= %u\n", net_ipv4);
        // 网络序转主机序
        host_ipv4 = ntohl(net_ipv4);
        printf("host_ipv4 	= %u\n", host_ipv4);
        // 主机序转网络序
        net_ipv4 = htoln(host_ipv4);
        printf("net_ipv4 	= %u\n", net_ipv4);
       	// 网络序转点分制
        inet_ntop(AF_INET, &net_ipv4, strIpv4, INET_ADDRSTRLEN);
        printf("strIpv4 	= %s\n", strIpv4);
        
        return;
    }
    
    // IPv6
    static void ipv6_tp(char *Ipv6){
        uint32_t net_ipv6[4], host_ipv6[4];
        char strIpv6[64] = {0};
        // 点分十六制转网络序
        inet_pton(AF_INET6, Ipv6, net_ipv6);
        for(int i = 0; i < 4; i++){
            printf("net_ipv6[%d] = %u", i, net_ipv6[i]);
            if(i != 3) printf(" "); else printf("\n");
        }
        // 网络序转主机序
        for(int i = 0; i < 4; i++){
            host_ipv6[i] = ntohl(net_ipv6[i]);
        }
        for(int i = 0; i < 4; i++){
            printf("host_ipv6[%d] = %u", i, host_ipv6[i]);
            if(i != 3) printf(" "); else printf("\n");
        }
        // 主机序转网络序
        for(int i = 0; i < 4; i++){
            net_ipv6[i] = ntohl(host_ipv6[i]);
        }
        for(int i = 0; i < 4; i++){
            printf("net_ipv6[%d] = %u", i, net_ipv6[i]);
            if(i != 3) printf(" "); else printf("\n");
        }
        
        // 网络序转点分制
        inet_ntop(AF_INET6, net_ipv6, strIpv6, INET6_ADDRSTRLEN);
        printf("strIpv6 = %s\n", strIpv6);
        
        return;
    }
    
    int main(void)
    {
        char strIpv4[16] = {"192.168.1.1"};
        char strIPV6[64] = {"fe80::20c:29ff:fe3b:846f"};
        
    	ipv4_tp(strIpv4);
        
        ipv6_tp(strIPV6);
        
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    未完待续~

  • 相关阅读:
    量化交易:开发传统趋势策略之---双均线策略
    Sqli-labs靶场第17关详解[Sqli-labs-less-17]自动化注入-SQLmap工具注入
    Python如何远程连接设置密码的MongoDB库
    C++:重定义:符号重定义:变量重定义
    Metabase学习教程:视图-3
    学习心得07:C#
    102. 二叉树的层序遍历
    携职教育:中级经济师备考超强攻略,亲测有效,拿走不谢
    FPGA实现“乒乓操作”
    react:值得一看的“react哲学”
  • 原文地址:https://blog.csdn.net/weixin_42571882/article/details/125488653