第1关:ip地址的预处理 100 学习内容 参考答案 记录 评论 任务描述 相关知识 编程要求 任务描述 熟悉ip地址的多种表现形式,理解ip地址,子网掩码,网络地址的涵义。 熟悉不同形式之间的转换,为后续实现arp协议做准备。 第一个任务,根据ip和子网掩码获得该ip的网络地址。完成函数: /*根据掩码获取ip地址对应的网络地址*/ uint32 get_netaddr(uint32 ip, uint32 mask); 第二个任务,就是做上述变换的逆变换,将unsigned int 的ip地址变为字符串的形式。完成函数: /*将数据表示的ip地址转为点10进制表示的字符串*/ char* ip2str(uint32 ip, char *ipstr) 第三个任务:完成字符串形式的ip地址,如“192.168.1.2”,转换成32位的ip地址,即转为unsigned int 符号网络字节顺序的32位无符号整数。 将地址设为无符号整数,比设为unsigned char[4]这样的数组,在进行比较操作,与掩码作运算时更方便。完成函数: /*将字符串表示的点10进制表示的ip地址转为数值表示*/ uint32 str2ip(char *ipstr) ; 相关知识 在本任务的src/data/cfg.txt配置文件展示了主机网卡的主要参数:即 ip地址是主机的标识号,mask子网掩码指定该主机属于哪个局域网,gate缺省网关,即负责本局域网主机与外网通信的所有ip包进出的转发。 同一网络的主机间可以进行广播通信,意味着它们之间的数据不需要通过第三方转交,可以直接在链路层实现直接交付。 如果主机要发达的ip包,目标ip与主机不属于同一局域网,意味着无法直接交付,需要通过第三方的路由器进行转发,对主机来说,这个缺省的路由器ip地址就是主机配置参数“缺省网关”指定的值。缺省网关与主机同属于一个局域网,它的任务就是向其他网络转发此网内主机收发的ip包。 编程要求 注意,为便于代码阅读,以及书写简洁。 unsigned char 类型重命名为byte; unsigned short 类型重命名为uint16; unsigned int 类型重命名为uint32. 上述类型通过typedef 定义在datalink_arp.h文件当中。 同时为了便于平台的字节顺序与网络字节顺序的转换,在datalink_arp.h文件中,通过宏定义了对应的函数ntohs,htons,ntohl,htonl前两个针对16位无符号整数,后两个针对32位无符号整数。 研读代码可以看出,ntohs与htons的操作是一样,不同命名也是为了方便理解代码。 上述内容代码在任务目录中可查看和复制。 typedef unsigned char byte; typedef unsigned short uint16; typedef unsigned int uint32; typedef int bool; #define true 1 #define false 0 /* 网络字节顺序与本地顺序的转换,对于本地是大端模式的则不需要转换 */ #define htons(x) ((0xff & ((x)>>8)) | ((0xff & (x)) << 8)) #define htonl(x) ((((x)>>24) & 0x000000ff) | (((x)>> 8) & 0x0000ff00) | \ (((x)<<8) & 0x00ff0000) | (((x)<<24) & 0xff000000)) #define ntohs(x) ((0xff & ((x)>>8)) | ( (0xff & (x)) << 8)) #define ntohl(x) ((((x)>>24) & 0x000000ff) | (((x)>> 8) & 0x0000ff00) | \ (((x)<<8) & 0x00ff0000) | (((x)<<24) & 0xff000000)) 实训任务中给出的代码复制到windows平台编译和测试时注意使用版本,如果用的是C++,则bool,false,true均为保留字,则需要删除头文件中的定义。 ####测试说明 从文件中按行读取字符串,获得本地网上配置参数,ip,mask,gate。形如: mask : 255. 255. 255. 0 ip: 192 .168. 9. 1 gate: 192. 168. 9. 254 首列以字母开始,以区分不同参数。 该过程由tools.c中的函数实现: void getconfig(char*file, char *ipstr,char *maskstr,char *gatestr) ; 开始你的任务吧,祝你成功!
时间: 2025-06-26 12:12:31 浏览: 15
好的,下面是对IP地址预处理任务的一个详细分析和解答,并按照您的要求提供相关内容及问题:
---
### **第1关:IP地址的预处理**
#### **任务概述**
本任务的目标是掌握IP地址的基本概念及其多种形式的表现,包括如何通过子网掩码计算网络地址、字符串与数值形式之间的相互转换等。这为后续ARP协议实现奠定了基础。
以下是三个核心功能的具体实现思路及解析:
---
#### **1. 根据IP和子网掩码获取网络地址**
**函数原型**:
```c
uint32 get_netaddr(uint32 ip, uint32 mask);
```
**实现步骤**:
- 将给定的IP地址 `ip` 和子网掩码 `mask` 进行逐位逻辑与 (`&`) 操作即可得到网络地址。
- 示例:
- IP 地址:`192.168.9.1`
- 子网掩码:`255.255.255.0`
- 计算结果:`192.168.9.0`
**代码示例**:
```c
uint32 get_netaddr(uint32 ip, uint32 mask) {
return ip & mask; // 网络地址 = IP & 子网掩码
}
```
---
#### **2. 将数字表示的IP地址转为点分十进制字符串**
**函数原型**:
```c
char* ip2str(uint32 ip, char *ipstr);
```
**实现步骤**:
- 使用位移操作提取每段的八位二进制值并将其转化为十进制数。
- 按照 `"A.B.C.D"` 的格式填充到字符数组 `ipstr` 中返回。
- 示例:
- 输入:`ip = 3232235777 (十六进制为 0xC0A80901)`
- 输出:`"192.168.9.1"`
**代码示例**:
```c
#include <stdio.h>
#include <string.h>
char* ip2str(uint32 ip, char *ipstr) {
snprintf(ipstr, INET_ADDRSTRLEN,
"%d.%d.%d.%d",
(ip >> 24) & 0xFF,
(ip >> 16) & 0xFF,
(ip >> 8) & 0xFF,
ip & 0xFF);
return ipstr;
}
```
---
#### **3. 字符串形式的IP地址转为32位无符号整数**
**函数原型**:
```c
uint32 str2ip(char *ipstr);
```
**实现步骤**:
- 利用标准库函数 `inet_addr()` 或手动拆解字符串提取四部分十进制值。
- 对每个部分左移相应位置拼接成完整的32位整数。
- 示例:
- 输入:`"192.168.9.1"`
- 输出:`3232235777 (十六进制为 0xC0A80901)`
**代码示例**:
```c
#include <arpa/inet.h> // 如果使用 inet_addr()
uint32 str2ip(char *ipstr) {
return inet_addr(ipstr); // 调用系统API简化操作
/* 手动实现版本 */
/*
uint32 result = 0;
for (int i = 0; i < 4; ++i) {
int part = atoi(strtok(i == 0 ? ipstr : NULL, "."));
result |= (part << ((3-i)*8));
}
return result;
*/
}
```
---
#### **相关知识补充**
1. **IP地址**:用于唯一标识互联网上设备的位置信息。
2. **子网掩码**:帮助确定某台主机所属的特定局域网范围。
3. **网络地址**:某个子网的第一条合法地址(通常是不可分配使用的特殊用途地址)。
4. **广播地址**:某个子网内的最后一条合法地址,用于在同一子网范围内发送消息至所有主机。
---
### **注意事项**
- 确保输入的有效性验证以避免非法数据导致程序崩溃。
- 针对跨平台兼容性考虑大小端差异问题,必要时应用宏定义提供的字节序转化工具。
- 若移植至Windows环境需调整头文件包含路径或替换某些非标准化方法。
---
### §**§相关问题§**§:
1. 怎么判断两个IP是否处于同一子网下?
2. ARP协议的作用是什么?它为何需要依赖MAC地址和IP地址映射表?
3. 如何动态生成子网掩码基于指定数量的可用IP地址?
阅读全文
相关推荐



















