当前位置: 首页 > article >正文

Linux网络编程:IP地址字符串格式与in_addr格式的相互转换

目录

1.字符串格式转in_addr格式

2.in_addr格式转字符串格式

3.补充:IPv4地址和IPv6地址的结构体


在基于IPv4/IPv6的Socket网络编程中,通常会使用sockaddr_in/sockaddr_in6结构体进行网络通信,sockaddr_in结构体中的成员sin_addr表示32位的IP地址,sockaddr_in6结构体中的成员sin6_addr表示128位的IP地址,这些都是in_addr格式的IP地址。但是我们通常使用点分十进制表示IP地址,而使用in_addr格式的IP地址比较复杂。

因此操作系统为我们提供了IP地址转换函数:支持IP地址在点分十进制字符串格式和in_addr格式的IP地址之间相互转换。

1.字符串格式转in_addr格式

int inet_pton(int af, const char *src, void *dst);

#include <arpa/inet.h>

int inet_pton(int af, const char *src, void *dst);

af:地址族,指定要转换的地址类型(AF_INET表示IPv4地址,AF_INET6表示IPv6地址)

src:指向包含点分十进制格式IP地址字符串的指针

dst:指向转换成功后存储IP地址的缓冲区的指针(IPv4地址下为struct in_addr结构体,IPv6地址下位struct in6_addr结构体)

返回值:成功返回1,失败返回-1并设置errno错误码(如果src不是有效的IP地址,返回0)

示例代码(IPv4地址):

#include <iostream>
#include <arpa/inet.h>
//IPv4地址
void test()
{
    //int inet_pton(int af, const char *src, void *dst);
    const char* ip_str="127.0.0.1";//字符串格式IP地址
    struct in_addr ip_bin;//in_addr格式IP地址
    int result=inet_pton(AF_INET,ip_str,&ip_bin);
    if(result==1)
        std::cout<<"转换成功,in_addr格式IP地址为:"<<ip_bin.s_addr<<std::endl;
    else if(result==0)
        std::cout<<"无效IP地址"<<std::endl;
    else
        std::cerr<<"转换失败"<<std::endl;
}
int main()
{
    test();
    return 0;
}

2.in_addr格式转字符串格式

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

#include <arpa/inet.h>

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

af:地址族,指定要转换的地址类型(AF_INET表示IPv4地址,AF_INET6表示IPv6地址)

src:指向存储网络字节序IP地址的缓冲区(IPv4地址下是指向struct in_addr的指针,IPv6地址下是指向struct in6_addr的指针)

dst:指向存储点分十进制字符串形式的IP地址缓冲区的指针

cnt:dst缓冲区的大小,单位为字节

返回值:成功返回只想dst的指针,失败返回NULL并设置errno错误码

示例代码:

//IPv4地址
void test()
{
    //const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt)
    struct in_addr ip_bin;
    ip_bin.s_addr=0x01020304;//假设存在一个in_addr格式的IPv4地址:1.2.3.4
    ip_bin.s_addr=htonl(ip_bin.s_addr);//要先将主机字节序IP地址转换为网络字节序IP地址
    char ip_str[1024];

    const char* result=inet_ntop(AF_INET,&ip_bin,ip_str,sizeof(ip_str));
    if(result==nullptr)
        std::cout<<"转换失败"<<std::endl;
    else   
        std::cout<<"转换成功,点分十进制字符串格式IP地址为:"<<ip_str<<std::endl;

}
int main()
{
    test();
    return 0;
}

3.补充:IPv4地址和IPv6地址的结构体

IPv4地址结构体

struct sockaddr_in {
    sa_family_t sin_family;  // 地址族,通常为 AF_INET 表示 IPv4
    uint16_t sin_port;       // 端口号,使用网络字节序
    struct in_addr sin_addr; // IPv4 地址,使用网络字节序
    char sin_zero[8];        // 填充字段,用于使结构体大小与 sockaddr 一致
};

struct in_addr {
    uint32_t s_addr;  // IPv4地址,以网络字节序存储
};

IPv6地址结构体 

struct sockaddr_in6 {
    sa_family_t sin6_family;   // 地址族,通常为 AF_INET6 表示 IPv6
    uint16_t sin6_port;        // 端口号,使用网络字节序
    uint32_t sin6_flowinfo;    // 流信息,通常设置为0
    struct in6_addr sin6_addr; // IPv6 地址,使用网络字节序
    uint32_t sin6_scope_id;    // 作用域标识,用于链路本地地址等
};

struct in6_addr {
    uint8_t s6_addr[16];  // IPv6地址,以网络字节序存储
};

http://www.kler.cn/a/419972.html

相关文章:

  • ElasticSearch easy-es 聚合函数 group by 混合写法求Top N 词云 分词
  • Git Rebase vs Merge:操作实例详解
  • Redis 之持久化
  • 前端开发 之 15个页面加载特效上【附完整源码】
  • 一款支持80+语言,包括:拉丁文、中文、阿拉伯文、梵文等开源OCR库
  • 分布式集群下如何做到唯一序列号
  • ubuntu 20.04 安装 docker 后遇到的网络问题
  • 在python中连接elasticsearch
  • 算法训练(leetcode)二刷第三十三天 | *322. 零钱兑换、*279. 完全平方数、*139. 单词拆分
  • 计算机网络 —— HTTP 协议(详解)
  • Matlab实现海洋捕食者优化算法优化随机森林算法模型 (MPA-RF)(附源码)
  • 2024年09月中国电子学会青少年软件编程(Python)等级考试试卷(三级)答案 + 解析
  • 【C++】——红黑树的平衡之道:深入实现与优化
  • 乐橙云小程序插件接入HbuilderX
  • 68 mysql 的 临键锁
  • Unity开发FPS游戏之完结篇
  • RDIFramework.NET CS敏捷开发框架 SOA服务三种访问(直连、WCF、WebAPI)方式
  • Java程序员最新场景面试题总结
  • Brain.js(二):项目集成方式详解——npm、cdn、下载、源码构建
  • 电子电气架构 --- 车载网关GW连接外部IP Tester
  • springboot371高校实习管理系统(论文+源码)_kaic
  • 鸿蒙Next星河版基础用例
  • Leetcode 第425场周赛分析总结
  • 力扣1382:将二叉搜索树便平衡
  • Scala的模式匹配变量类型
  • 方寸 i560 安全存储加密芯片 SoC 存储安全芯片技术手册