Linux C/C++ 网络编程中地址格式转换(inet_pton和inet_ntop函数)

news/2024/10/17 12:20:43/

网络编程中地址格式转换(inet_pton和inet_ntop函数)

地址格式转换

#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>int  inet_pton(int  af ,  const  char  * src  ,void   *  dst);

(1)功能:将点分十进制格式的地址字符串转换为网络字节序整型数

(2)返回值:成功返回1,错误返回-1

(3)参数:

     ----af   :转换格式 AF_INET(IPV4)或者AF_INET6(IPV6)---- src :点分格式的地址----- dst:转换后的整型变量的地址
const char *  inet_ntop(int  af , const  void  * src ,  char * dst , socklen_t   cnt);

(1)功能:将网络字节序整型数转换为点分格式的IP地址

(2)返回值:成功返回转换后的地址,错误返回NULL

(3)参数:

     ----af   :转换格式 AF_INET(IPV4)或者AF_INET6(IPV6)---- src :整型变量的地址----- dst:用来存储转换后的数据的地址------cnt:存储空间的大小

错误处理

在使用 inet_ptoninet_ntop 函数时,可能会出现一些错误。为了确保程序的稳定性,我们需要对这些错误进行适当的处理。通常情况下,我们可以使用 perror 函数来打印出具体的错误信息。下面我们将详细介绍如何处理这两个函数的错误,并给出一个错误处理的例子。

首先,我们需要注意 inet_pton 函数的返回值。当成功将地址字符串转换为网络字节序整数时,它会返回 1;如果输入的地址字符串无效,它会返回 0;发生错误时,它会返回 -1。因此,在调用 inet_pton 后,我们需要检查返回值,以确定是否发生了错误。如果返回值为 -1,我们可以使用 perror 函数打印出具体的错误信息。

同样地,对于 inet_ntop 函数,当成功将网络字节序整数转换为点分格式的 IP 地址时,它会返回转换后的地址;如果发生错误,它会返回 NULL。因此,在调用 inet_ntop 后,我们需要检查返回值,以确定是否发生了错误。如果返回值为 NULL,我们可以使用 perror 函数打印出具体的错误信息。

下面是一个处理错误的示例:

#include <stdio.h>
#include <stdlib.h>  
#include <sys/types.h>  
#include <sys/socket.h>  
#include <arpa/inet.h>  
#include <string.h>  
#include <netdb.h>  int main()  
{  int addrnum;  char addrstring[] = "Invalid IP address";  printf("Address in dotted-quad format is %s\\n", addrstring);  if (inet_pton(AF_INET, addrstring, &addrnum) == -1) {perror("inet_pton");exit(EXIT_FAILURE);}char addrstring2[16] = "";if (inet_ntop(AF_INET, &addrnum, addrstring2, 16) == NULL) {perror("inet_ntop");exit(EXIT_FAILURE);}printf("Address in dotted-quad format is %s\\n", addrstring2);  return 0;  
}

运行结果:

  1. Address in dotted-quad format is Invalid IP address
  2. inet_pton: Invalid argument

在上面的示例中,我们使用了一个无效的 IP 地址字符串。当调用 inet_pton 函数时,它会返回 -1,表示发生了错误。我们使用 perror 函数打印出错误信息 “Invalid argument”,这表明输入的地址字符串无效。通过这种方式,我们可以轻松地处理 inet_ptoninet_ntop 函数的错误,并确保程序的稳定性。

示例

IPV4

#include <stdio.h>#include <stdlib.h>  
#include <sys/types.h>  
#include <sys/socket.h>  
#include <arpa/inet.h>  
#include <string.h>  
#include <netdb.h>  
int main()  
{  int addrnum;  char addrstring[16] = "127.0.0.1";  printf("address in dotted-quad format is %s\\n",addrstring);  inet_pton(AF_INET,addrstring,&addrnum);  printf("address in network byteorder integer is 0x%x\\n",addrnum);  char addrstring2[16] = "";  if(inet_ntop(AF_INET,&addrnum,addrstring2,16) == NULL)  {  perror("inet_ntop");  }  printf("address in dotted - quad format is %s \\n",addrstring2);  return 0;  }     

运行结果:

[root@rac2 ~]# ./addrformat

  1. address in dotted-quad format is 127.0.0.1
  2. address in network byteorder integer is 0x100007f
  3. address in dotted - quad format is 127.0.0.1

IPV6

#include <stdio.h>
#include <stdlib.h>  
#include <sys/types.h>  
#include <sys/socket.h>  
#include <arpa/inet.h>  
#include <string.h>  
#include <netdb.h>  int main()  
{  int addrnum;  char addrstring[INET6_ADDRSTRLEN] = "2001:0db8:85a3:0000:0000:8a2e:0370:7334";  printf("IPv6 address in hexadecimal notation is %s\\n", addrstring);  struct in6_addr addrnum6;if (inet_pton(AF_INET6, addrstring, &addrnum6) != 1) {perror("inet_pton");exit(EXIT_FAILURE);}char addrstring2[INET6_ADDRSTRLEN] = "";if (inet_ntop(AF_INET6, &addrnum6, addrstring2, INET6_ADDRSTRLEN) == NULL) {perror("inet_ntop");exit(EXIT_FAILURE);}printf("IPv6 address in hexadecimal notation is %s\\n", addrstring2);  return 0;  
}

在C++ 中的使用示例

在 C++ 中,我们可以使用 RAII(Resource Acquisition Is Initialization)技术和异常处理机制来优雅地使用 inet_ptoninet_ntop 函数。下面是一个综合示例,包含注释和异常捕获:

#include <iostream>
#include <stdexcept>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <cstring>class IPAddress
{
public:IPAddress(const std::string& address, int family): family_(family){if (family == AF_INET) {if (inet_pton(AF_INET, address.c_str(), &addr_.ipv4) != 1) {throw std::runtime_error("Invalid IPv4 address: " + address);}}else if (family == AF_INET6) {if (inet_pton(AF_INET6, address.c_str(), &addr_.ipv6) != 1) {throw std::runtime_error("Invalid IPv6 address: " + address);}}else {throw std::runtime_error("Invalid address family");}}std::string toString() const{char buffer[INET6_ADDRSTRLEN];const char* result = inet_ntop(family_, &addr_, buffer, sizeof(buffer));if (result == nullptr) {throw std::runtime_error("Address conversion failed");}return std::string(buffer);}private:union {struct in_addr ipv4;struct in6_addr ipv6;} addr_;int family_;
};int main()
{try {// IPv4 示例IPAddress ipv4("192.168.1.1", AF_INET);std::cout << "IPv4 address: " << ipv4.toString() << std::endl;// IPv6 示例IPAddress ipv6("2001:0db8:85a3:0000:0000:8a2e:0370:7334", AF_INET6);std::cout << "IPv6 address: " << ipv6.toString() << std::endl;}catch (const std::runtime_error& e) {std::cerr << "Error: " << e.what() << std::endl;return 1;}return 0;
}

应用场景

地址转换在网络编程中具有广泛的应用场景。它的主要作用是在不同表示格式之间进行转换,以便于在各种网络通信和地址解析任务中使用。下面我们将简要介绍地址转换在实际应用场景中的一些用途。

  1. 网络通信:在网络编程中,我们需要与不同的网络设备进行通信。设备之间的通信通常使用网络字节序(大端字节序)表示的整数进行。而人们在日常使用中,通常使用点分十进制(IPv4)或者冒分十六进制(IPv6)表示的 IP 地址。因此,在实际编程过程中,我们需要将人类可读的地址转换为网络字节序整数,或者将网络字节序整数转换为人类可读的地址。这就需要使用 inet_ptoninet_ntop 等地址转换函数。

  2. 地址解析:在许多网络应用中,我们需要根据域名来获取 IP 地址。这个过程通常涉及到 DNS 查询,返回的 IP 地址通常以网络字节序整数的形式表示。为了方便展示和使用,我们需要将这些整数地址转换为点分十进制或冒分十六进制表示的字符串。这时,inet_ntop 函数就派上了用场。

  3. 跨平台兼容性:不同的计算机系统和网络设备可能使用不同的字节序。为了确保跨平台的兼容性,网络通信通常采用网络字节序(大端字节序)表示整数。地址转换函数如 inet_ptoninet_ntop 能够确保在不同平台之间进行正确的转换,从而提高了跨平台应用的兼容性。

  4. 网络诊断与调试:在网络诊断和调试过程中,我们需要处理各种地址信息。地址转换函数可以帮助我们将不同格式的地址信息转换为可读的形式,便于分析和排查问题。

通过以上介绍,我们可以看到地址转换在实际网络编程场景中具有重要的作用。掌握 inet_ptoninet_ntop 等地址转换函数的使用,能够帮助我们更加高效地处理网络通信和地址解析等任务。


http://www.ppmy.cn/news/59405.html

相关文章

iOS中的autorelease

iOS中的autorelease是一种非常重要的内存管理机制&#xff0c;它可以自动释放对象&#xff0c;从而避免内存泄漏和内存溢出等问题。在本文中&#xff0c;我们将详细介绍iOS中的autorelease机制&#xff0c;包括它的原理、使用方法以及注意事项等内容。 autorelease的原理 aut…

【模块系列】DY-SV17F语音播放模块

前言 本文针对官方给的应用手册进行补充和加上个人理解。在官方的资料中已经介绍的很详细了&#xff0c;我就节选部分出来&#xff0c;基本认识模块就行了吧。本来还行自己介绍呢&#xff0c;没想到官方写这么详细了&#xff0c;也不知道介绍啥了&#xff0c;现在单纯的写为个人…

提升自我数据分析能力的根本,是方法论!

很多人问&#xff0c;我是财务&#xff0c;能转行业做BI吗&#xff1f;我该学些什么&#xff1f;该掌握哪些技能&#xff1f;该如何学习&#xff1f;我是学生&#xff0c;在校期间专业不扎实&#xff0c;该怎么办&#xff1f;我是小白&#xff0c;还能学会数据分析吗&#xff1…

【软考高项笔记】第1章 信息化发展1.3 现代化创新发展

1.3 现代化创新发展 1.3.1 农业农村现代化 采棉机&#xff0c;传感器检查温度湿度 乡村振兴战略 建设基础设施 发展智慧农业 建设数据乡村1.3.2 两化融合与智能制造&#xff08;工业&#xff09; 信息化 工业化 发展战略 坚持自主可控&#xff0c;安全高效&#xff0c;推进产业…

java反序列化cc3链分析

前言 休息完五一&#xff0c;继续卷&#xff0c;原本想结束cc链的&#xff0c;但是发现cc3链好像用的方法不太一样&#xff0c;感觉也是可以记录下来&#xff0c;这里感觉cc3链有一些像cc1链的变种&#xff0c;就像是给你一些绕过的操作 在说一句&#xff0c;白日梦组长永远的神…

Qt 基本概念理解

1、如何理解Qt支持跨平台&#xff1f; 答&#xff1a;我们经常听到这样的说法“如果考虑跨平台的话&#xff0c;qt是一个很好的选择”&#xff0c;感性认识上可能有一个模糊的认识&#xff0c;好像是这么回事&#xff0c;但是往深处想一想&#xff0c;可能又不知道所以然。这里…

什么是http代理504网关超时错误,要如何修复?

当你在使用 HTTP 代理时&#xff0c;有时候会遇到"504 网关超时"错误&#xff0c;这个错误看起来非常可怕&#xff0c;但实际上它并不是一个很难解决的问题。在本文中&#xff0c;我将向你介绍 504 错误的定义&#xff0c;以及为什么我们会遇到这个错误&#xff0c;同…

Redis-列表(List)

Redis列表(List) 介绍 单键多值Redis 列表是简单的字符串列表&#xff0c;按照插入顺序排序。你可以添加一个元素到列表的头部&#xff08;左边&#xff09;或者尾部&#xff08;右边&#xff09;它的底层实际是个双向链表&#xff0c;对两端的操作性能很高&#xff0c;通过索…