Linux Socket学习--地址转换函数

简介:

     一个IP地址是由小数点分开的十进制数表示的,我们称之为点分十进制表示法。其中每一个十进制数代表一个字节的无符号数值(按照网络字节序)因为每个字节都是无符号的8位数值,这就限制了每一个字节所能表示的范围是0~255.

Internet地址分类

     一个Internet地址是由网络地址和主机地址构成的。

     我们知道IP地址由32位二进制构成,但是网络地址和主机地址之间的界限并不是固定的,而界限的确定取决于地址的分类,下表总结了IP地址分类的方法:

image

理解网络掩码:

     网络掩码的作用在于把网络地址从IP地址从提取出来,实际上代表网络掩码的IP号和某一特定的IP地址进行“按位与”操作。

     如果我们需要建立自己的IP网络,那么就必须确定网络掩码,如下图:

image

软件有时候需要提供将IP地址进行分类的能力,下面的例子就展示了这个操作:

---------UNDONE(此处代码待添加)

分配IP地址

     ip地址是通过InterNIC分配给不同的组织和个人的。但是并非所有的IP地址都是可以用来分配的,其中也有一些私有的,或者说是预留出来的。

私有IP

      一般IP地址都需要在InterNIC进行登记,但是如果你的系统没有直接连接到Internet,那么久不需要全球唯一的地址,这个时候就可以使用私有IP地址来替代。

      RFC1597就是描述怎么分配私有IP地址的文档。

      image

最后到底选择哪一种IP地址在很大的程度上取决于所需要建立的网络数量,分离的网段以及每个网段上主机的数目。

保留IP地址

   保留IP地址的数量很多,在RFC1166文档中有记录。下面就是一个保留IP地址的实例:

image

操作IP地址

    inet_addr()函数的语法如下:

#include <sys/socket.h>
#include <neiinet/in.h>

#include <arpa/inet.h>

unsigned long inet_addr(const char * string);

        这个函数使用string作为输入参数,并将这个点分十进制的IP地址转换为32位的二进制表示法,函数的返回值就是这个32位的二进制的网络字节序。当然如果string不是一个有效的点分十进制IP地址,函数返回INADDR_NONE。另外需要注意的是,当inet_addr函数返回INADDR_NONE的时候,它并没有建立一个有效的errno值,所以当函数返回错误的时候,不要去测试errno的值。

        下面的这个例子展示了如何使用函数inet_addr。

       。。。。。。。。。UNDONE(此处代码待添加)

       注意:

       在新程序中避免使用inet_addr函数,而应该使用inet_aton函数作为代替。因为对于inet_addr函数来说,即使输入的参数是有效的IP地址:255.255.255.255,他的返回值仍然是INADDR_NONE。

下面我们来说说inet_aton函数:

     inet_aton函数是将字符串形式的IP地址转换为网络字节序的32位IP地址的改进形式。语法如下:

#include <sys/socket.h>
#include <neiinet/in.h>
#include <arpa/inet.h>

int inet_aton(const char* string, struct in_addr*addr);

参数string表示点分十进制IP地址的ASCII表示。输出参数addr是一个被新的IP地址跟新的结构。函数调用成功返回非0值。失败返回0.当然他也没有建立一个有效的errno值。下面的代码展示了inet_aton函数的用法:

。。。。。。。。。UNDONE(此处代码待添加)

下面我们来看看inet_ntoa函数

        有时候当用户连接到你的服务器的时候,需要知道他的IP地址,系统提供了inet_ntoa函数将32位的二进制IP地址表示转换为点分十进制的字符串形式:

#include <sys/socket.h>
#include <neiinet/in.h>
#include <arpa/inet.h>

char* inet_ntoa(struct in_addr addr);

下面的代码展示了如何使用inet_ntoa函数:

。。。。。。。。。UNDONE(此处代码待添加)

       需要注意的是inet_ntoa函数的返回值直到下次调用前一直有效。所以如果在线程中使用inet_ntoa的时候,一定要确保每次只有一个线程调用本函数。否则一个线程的返回的结构可能被其他线程返回的结果所覆盖。

接下来我们来看看inet_network函数。

        当我们需要用网络掩码将IP地址中的网络位或者主机位提取出来的时候,如果能将点分十进制的IP地址转换为主机字节序的32位二进制IP地址形式就方便了,而inet_network函数的作用就是如此、语法如下:

#include <sys/socket.h>
#include <neiinet/in.h>
#include <arpa/inet.h>

unsigned long inet_network(const char* addr);

函数的输入参数是存储在字符串addr中的点分十进制IP地址,返回值是主机字节序的32位二进制地址,但是如果输入参数不正确,返回值是0xFFFFFFFF.

    以主机字节序的形式返回结果可以保证用户安全的使用网络掩码,因为如果返回值是网络字节序的话,那么不同的cPu平台所使用的网络掩码和程序代码就会有差异。下面的例子展示了如何使用inet_network函数。

。。。。。。。。。UNDONE(此处代码待添加)

我们来看看inet_lnaof函数。

        函数inet_lnaof函数是将套接口地址中的IP地址(网络字节序)转换为没有网络位的主机ID(主机字节序),这个函数为我们省去了很多的麻烦,因为我们不需要对IP地址进行分类,再将主机为从IP地址中提取出来。函数语法如下:

#include <sys/socket.h>
#include <neiinet/in.h>
#include <arpa/inet.h>

unsigned long inet_lnaof(struct in_addr addr);

下面的表提供了一些可以作为inet_lnaof函数输入的典型例子和返回值:

image

我们再来看看inet_netof函数

      inet_lnaof函数返回的是主机ID,而inet_netof函数返回的是网络ID,函数语法如下:

#include <sys/socket.h>
#include <neiinet/in.h>
#include <arpa/inet.h>

unsigned long inet_netof(struct in_addr addr);

下表展示了一些例子:

image

然后我们再来看看inet_makeaddr函数吧。根据之前的内容我们知道使用inet_netof函数和inet_lnaof函数,我们就可以把IP地址中的主机为和网络位分别提取出来,有时候我们还需要根据提取出来的主机位和网络为合并为一个新的IP地址。这个时候我们就可以使用inet_makeaddr函数。

#include <sys/socket.h>
#include <neiinet/in.h>
#include <arpa/inet.h>

struct in_addr inet_makeaddr(int net , int host);

下面的例子展示了上面讲到的三个函数:

。。。。。。。。。UNDONE(此处代码待添加)


==============================================================================
本文转自被遗忘的博客园博客,原文链接:http://www.cnblogs.com/rollenholt/archive/2012/08/16/2642366.html,如需转载请自行联系原作者
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
相关文章
|
Linux 编译器 开发工具
【Linux快速入门(三)】Linux与ROS学习之编译基础(Cmake编译)
【Linux快速入门(三)】Linux与ROS学习之编译基础(Cmake编译)
728 2
|
存储 安全 Linux
|
9月前
|
JavaScript Linux Python
在Linux服务器中遇到的立即重启后的绑定错误:地址已被使用问题解决
总的来说,解决"地址已被使用"的问题需要理解Linux的网络资源管理机制,选择合适的套接字选项,以及合适的时间点进行服务重启。以上就是对“立即重启后的绑定错误:地址已被使用问题”的全面解答。希望可以帮你解决问题。
481 20
|
10月前
|
存储 IDE Linux
零基础保姆级教程!手把手教你免费玩转Linux CentOS安装+学习环境搭建(附避坑指南)
本文详细介绍了在VMware虚拟机中安装CentOS 6.8的全过程。首先,需确保已安装VMware并开启V-CPU虚拟化功能,可通过BIOS设置或使用LeoMoon CPU-V工具检测。接着,下载CentOS镜像文件,并在VMware中新建虚拟机,配置CPU、内存、硬盘等参数。最后,加载ISO镜像启动虚拟机,按照提示完成CentOS的安装,包括语言、键盘、存储方式、地区、密码设置及硬盘分区等步骤。安装完成后,以root用户登录即可进入系统桌面,开始学习Linux命令和操作。
1044 12
零基础保姆级教程!手把手教你免费玩转Linux CentOS安装+学习环境搭建(附避坑指南)
|
11月前
|
存储 Linux
linux中的目录操作函数
本文详细介绍了Linux系统编程中常用的目录操作函数,包括创建目录、删除目录、读取目录内容、遍历目录树以及获取和修改目录属性。这些函数是进行文件系统操作的基础,通过示例代码展示了其具体用法。希望本文能帮助您更好地理解和应用这些目录操作函数,提高系统编程的效率和能力。
383 26
|
Linux
【Linux】System V信号量详解以及semget()、semctl()和semop()函数讲解
System V信号量的概念及其在Linux中的使用,包括 `semget()`、`semctl()`和 `semop()`函数的具体使用方法。通过实际代码示例,演示了如何创建、初始化和使用信号量进行进程间同步。掌握这些知识,可以有效解决多进程编程中的同步问题,提高程序的可靠性和稳定性。
708 19
|
Linux Android开发 开发者
linux m、mm、mmm函数和make的区别
通过理解和合理使用这些命令,可以更高效地进行项目构建和管理,特别是在复杂的 Android 开发环境中。
706 18
|
存储 监控 Linux
嵌入式Linux系统编程 — 5.3 times、clock函数获取进程时间
在嵌入式Linux系统编程中,`times`和 `clock`函数是获取进程时间的两个重要工具。`times`函数提供了更详细的进程和子进程时间信息,而 `clock`函数则提供了更简单的处理器时间获取方法。根据具体需求选择合适的函数,可以更有效地进行性能分析和资源管理。通过本文的介绍,希望能帮助您更好地理解和使用这两个函数,提高嵌入式系统编程的效率和效果。
575 13
|
Linux Shell 数据安全/隐私保护
Linux 初学者必学的 10 个命令,学习!
【10月更文挑战第28天】
342 1
Linux 初学者必学的 10 个命令,学习!
|
Linux 编译器 C语言
【Linux快速入门(一)】Linux与ROS学习之编译基础(gcc编译)
【Linux快速入门(一)】Linux与ROS学习之编译基础(gcc编译)
328 2