处理Linux网络编程中的IP地址

简介: Linux网络服务能力非常强大,它的TCP/IP代码是最高级的。Linux的网络实现是模仿FreeBSD的,它支持FreeBSD的带有扩展的Sockets(套接字)和TCP/IP协议。它支持两个主机间的网络连接和Sockets通讯模型,实现了两种类型的Sockets:BSD Sockets和INET Sockets。

 Linux网络服务能力非常强大,它的TCP/IP代码是最高级的。Linux的网络实现是模仿FreeBSD的,它支持FreeBSD的带有扩展的Sockets(套接字)和TCP/IP协议。它支持两个主机间的网络连接和Sockets通讯模型,实现了两种类型的Sockets:BSD Sockets和INET Sockets。它为不同的通信模型和服务质量提供了两种传输协议,即不可靠的、基于消息的UDP传输协议和可靠的、基于流的传输协议TCP,并且都是在IP网络协议上实现的。INET sockets是在以上两个协议及IP协议之上实现的。它们之间的关系见图1所示。

图1 Linux网络层

Socket在网络编程中的实现

套接字是网络通信的基本构件,它提供了不同主机间进程双向通信的端点。如同电话一样,只有当一方拨通另一方的电话时,双方才能建立对话,套接字就好比是双方的电话。通过Sockets编程,程序可以跳过复杂的网络底层协议和结构,直接编制与平台无关的应用程序。随着Internet的广泛应用,Sockets已逐渐成为网络编程的通用接口。

套接字存在于特定的通信域(即地址族)中,只有隶属于同一地址族的套接字才能建立对话。Linux支持AF_INET(IPv4协议)、AF_INET6(IPv6协议)和AF_LOCAL(Unix域协议)。

Linux支持以下的socket families或domain:

◆ Unix domain sockets;

◆ INET TneIntemet address family supports communications via;

◆ TCP/IP protocols;

◆ Amateur radio X.25;

◆ Novel IPX;

◆ Appletalk DDP;

◆ X.25。

套接口就是网络进程的ID。网络通信也是一种进程的通信,两个网络进程通信时首先要确定各自所在网络节点的网络地址(IP地址)。网络地址可以确定进程所在的计算机,一台计算机上可能同时有多个网络进程。为了区别不同的进程,套接口中还需要端口号(Port)信息。在一台计算机中,一个端口一次只能分配给一个进程。所以在一台计算机中,端口号和进程可以惟一确定整个Intemet中的一个网络进程。可以认为,套接口=网络地址+端口号。

Linux网络数据结构

在网络实际传送的数据中,有两种字节排列顺序:重要的字节在前面,或者不重要的字节在前面。前一种叫网络字节顺序(Network Byte Order,NBO),有些机器在内部是按照这个顺序储存数据的。当某数据必须按照NBO顺序时,那么要调用函数(例如htons())将它从本机字节顺序(Host Byte Order,HBO)转换过来,否则传送过去的数据将使对方机器不可读。这点对于网络数据传送来说是非常关键的。

在网络中第一个被创造的结构类型是sockaddr。这个数据结构是为许多类型的套接口储存地址信息。它的定义如下:

																
     
      struct sockaddr{
  unsigned short  sa_family; /*这个是地址族,通常是AF-xxxx的形式*/
  char  sa_data[14];     /*14字节的地址信息*/
  };
     
     
														

上面代码中,sa_famdly是“AF_INET”,表示它使用的是Internet地址族;sa_data用于为套接口储存目标地址和端口信息。

为了解决struct sockaddr,创造了一个并列的结构struct sockadd_in(“in”代表“Internet”),如下所示:

																
     
      struct sockaddr_in{
short int   sin_family;  /*地址族信息,通常是AF-xxxx的形式*/
unsigned short    int sin_port; /*端口信息*/
struct in_addr    sin_addr;     /*网络地址*/
unsigned char     sin_zero[8];  /*补位用的0*/
}
     
     
														

上面这个数据结构可以轻松处理套接口地址的基本元素。需要解释的是,sin_zero被加入到这个结构中主要是为了保证struct sockaddr的数据长度和struct sockaddr_in的一样,这样在使用标准函数时,就可以使用统一的数据接口。需要注意的是,应该使用函数bzero()将sin_zero全部置零。最后,sin_port和sin_addb必须是网络字节顺序(Network Byte Order)。如果声明“inadd”是数据结构stmct sockaddr_in的实例,那么inadd.sinadd.s_addr就储存了4个字节的IP地址(网络字节顺序)。

另一个常用到的是unsigned类型。它比上面介绍的struct sockaddr_in或struct sockaddr用得更普遍。对于变量类型unsigned,可以使用的两种类型是short(两个字节)和long(四个字节)。假设想将short从本机字节顺序转换为网络字节顺序,需用“h”表示本机(host),用“to”表示进行转换,然后用“n”表示网络,用“s”表示short,那么就是h-to-n-s或者htons()(“Host to Network Short”)。

考虑到对不同机器的可移值性,这样的转换是必需的。我们对“n”、“h”、“s”和“l”这几个字母进行组合,就可以得到Linux下的全部转换函数。

IP地址在Linux网络中的处理方法

假设使用struct sockaddr_in ina,想将IP地址“164.112.175.124”储存到其中,那么所要做的是调用函数inet_addr(),转换上面“数字 + 句点”格式的IP地址到unsigned long中。这个工作可以这样来做:

																
     
      ina.sin_addr.s_addr=inet_addr(”164.112.175.124”);
     
     
														

inet_addr()返回的地址已经是按照网络字节顺序的,不用调用htonl()。在发生错误的时候inet_addr()返回-1。调用后,需使用正确的错误检查,比如说当IP地址为255.255.255.255的时候,返回的就是(unsigned)-1。因为这是个广播地址,你的程序必需能够将这类错误捕获出来。

你现在就可以转换字符串形式的IP地址为1ong了。若有一个数据结构struct in_addr,按照“数字+句点”格式打印时,你要用函数inet_ntoa()(ntoa意思是network to ascⅡ),如下所示:

																
     
      printf(“%s”,inet_ntoa(ina.sin_addr));
     
     
														

这样就可以打印IP地址。注意:函数inet—ntoa()的参数是struct in_addr,而不是long,它返回的是一个指向字符的指针。

在inet_ntoa内储存了字符数组,因此它每次调用inet_ntoa()的时候将覆盖以前的内容。

例如:

																
     
      Char a1,  *a2;
......
a1=inet_ntoa(ina1.sin_addr); /*假设地址是;164.112.175.124*/
a2=inet_ntoa(ina2.sin_addr);/*假设地址是:202.112.58.200*/
printf(“address 1:%s\n”,a1);
printf(“address 2:%s\n”,a2);
     
     
														

上面运行结果是:

																
     
      address l:202.112.58.200
address 2:202.112.58.200
     
     
														

如果想保存地址,那么可用strcpy()保存到自己的字符数组中。

以上介绍了Linux网络编程的基础知识和对网络IP地址处理的一些技巧。如果能够将其同Linux下众多的小工具整合在一起的话,那么所开发出来的程序的功能已经不亚于一些专业的软件了。

目录
相关文章
|
6天前
|
JSON 运维 Ubuntu
Linux下如何使用Curl进行网络请求
希望这篇文章能帮助您在Linux下更好地使用Curl进行网络请求。如有疑问,请随时提问!
45 10
|
4月前
|
监控 安全 Linux
在 Linux 系统中,网络管理是重要任务。本文介绍了常用的网络命令及其适用场景
在 Linux 系统中,网络管理是重要任务。本文介绍了常用的网络命令及其适用场景,包括 ping(测试连通性)、traceroute(跟踪路由路径)、netstat(显示网络连接信息)、nmap(网络扫描)、ifconfig 和 ip(网络接口配置)。掌握这些命令有助于高效诊断和解决网络问题,保障网络稳定运行。
172 2
|
2月前
|
Linux 网络性能优化 网络安全
Linux(openwrt)下iptables+tc工具实现网络流量限速控制(QoS)
通过以上步骤,您可以在Linux(OpenWrt)系统中使用iptables和tc工具实现网络流量限速控制(QoS)。这种方法灵活且功能强大,可以帮助管理员有效管理网络带宽,确保关键业务的网络性能。希望本文能够为您提供有价值的参考。
208 28
|
26天前
|
人工智能 安全 算法
IP地址、SSL与DeepSeek:现代网络安全的三角防线
在数字化浪潮中,IP地址、SSL协议与AI大模型DeepSeek分别作为网络通信的标识、加密护盾和智能防御核心,共同重塑网络安全范式。本文从技术原理、实践挑战与防御策略三个维度解析其融合价值与未来趋势。IP地址是设备的唯一标识,但易被攻击者利用;SSL通过加密确保数据安全;DeepSeek则通过AI实现智能威胁检测。三者的协同作用,为网络安全提供了全新的解决方案。未来将面临量子计算、AI对抗升级等挑战,需加速技术创新与安全意识提升,构建“协议可信+地址可控+AI赋能”的三维防线,以应对日益复杂的网络安全环境。
|
2月前
|
网络协议 Unix Linux
深入解析:Linux网络配置工具ifconfig与ip命令的全面对比
虽然 `ifconfig`作为一个经典的网络配置工具,简单易用,但其功能已经不能满足现代网络配置的需求。相比之下,`ip`命令不仅功能全面,而且提供了一致且简洁的语法,适用于各种网络配置场景。因此,在实际使用中,推荐逐步过渡到 `ip`命令,以更好地适应现代网络管理需求。
72 11
|
2月前
|
Ubuntu Linux 开发者
Ubuntu20.04搭建嵌入式linux网络加载内核、设备树和根文件系统
使用上述U-Boot命令配置并启动嵌入式设备。如果配置正确,设备将通过TFTP加载内核和设备树,并通过NFS挂载根文件系统。
152 15
|
3月前
|
Ubuntu Unix Linux
Linux网络文件系统NFS:配置与管理指南
NFS 是 Linux 系统中常用的网络文件系统协议,通过配置和管理 NFS,可以实现跨网络的文件共享。本文详细介绍了 NFS 的安装、配置、管理和常见问题的解决方法,希望对您的工作有所帮助。通过正确配置和优化 NFS,可以显著提高文件共享的效率和安全性。
380 7
|
4月前
|
网络安全 Python
Python网络编程小示例:生成CIDR表示的IP地址范围
本文介绍了如何使用Python生成CIDR表示的IP地址范围,通过解析CIDR字符串,将其转换为二进制形式,应用子网掩码,最终生成该CIDR块内所有可用的IP地址列表。示例代码利用了Python的`ipaddress`模块,展示了从指定CIDR表达式中提取所有IP地址的过程。
114 6
|
4月前
|
网络协议 安全 文件存储
动态DNS(DDNS)技术在当前网络环境中日益重要,它允许使用动态IP地址的设备通过固定域名访问
动态DNS(DDNS)技术在当前网络环境中日益重要,它允许使用动态IP地址的设备通过固定域名访问,即使IP地址变化,也能通过DDNS服务保持连接。适用于家庭网络远程访问设备及企业临时或移动设备管理,提供便捷性和灵活性。示例代码展示了如何使用Python实现基本的DDNS更新。尽管存在服务可靠性和安全性挑战,DDNS仍极大提升了网络资源的利用效率。
260 6
|
5月前
|
运维 监控 网络协议