报文格式 为了便于实现,我们简化地规定 DHCP 数据报文的格式如下:
DHCP 数据报文的各个部分由空格分隔,其各个部分的定义如下:
发送主机:是发送报文的主机名,主机名是由小写字母、数字组成的字符串,唯一地表示了一个主机; 接收主机:当有特定的接收主机时,是接收报文的主机名;当没有特定的接收主机时,为一个星号(*); 报文类型:是三个大写字母,取值如下: DIS:表示 Discover 报文; OFR:表示 Offer 报文; REQ:表示 Request 报文; ACK:表示 Ack 报文; NAK:表示 Nak 报文; IP 地址,是一个非负整数: 对于 Discover 报文,该部分在发送的时候为 0,在接收的时候忽略; 对于其它报文,为正整数,表示一个 IP 地址; 过期时刻,是一个非负整数: 对于 Offer、Ack 报文,是一个正整数,表示服务器授予客户端的 IP 地址的过期时刻; 对于 Discover、Request 报文,若为正整数,表示客户端期望服务器授予的过期时刻; 对于其它报文,该部分在发送的时候为 0,在接收的时候忽略。 例如下列都是合法的 DHCP 数据报文:
a * DIS 0 0 d a ACK 50 1000
服务器配置 为了 DHCP 服务器能够正确分配 IP 地址,DHCP 需要接受如下配置:
地址池大小 :表示能够分配给客户端的 IP 地址的数目,且能分配的 IP 地址是 ; 默认过期时间 :表示分配给客户端的 IP 地址的默认的过期时间长度; 过期时间的上限和下限 、:表示分配给客户端的 IP 地址的最长过期时间长度和最短过期时间长度,客户端不能请求比这个更长或更短的过期时间; 本机名称 :表示运行 DHCP 服务器的主机名。 分配策略 当客户端请求 IP 地址时,首先检查此前是否给该客户端分配过 IP 地址,且该 IP 地址在此后没有被分配给其它客户端。如果是这样的情况,则直接将 IP 地址分配给它,否则, 总是分配给它最小的尚未占用过的那个 IP 地址。如果这样的地址不存在,则分配给它最小的此时未被占用的那个 IP 地址。如果这样的地址也不存在,说明地址池已经分配完毕,因此拒绝分配地址。
实现细节 在 DHCP 启动时,首先初始化 IP 地址池,将所有地址设置状态为未分配,占用者为空,并清零过期时刻。 其中地址的状态有未分配、待分配、占用、过期四种。 处于未分配状态的 IP 地址没有占用者,而其余三种状态的 IP 地址均有一名占用者。 处于待分配和占用状态的 IP 地址拥有一个大于零的过期时刻。在到达该过期时刻时,若该地址的状态是待分配,则该地址的状态会自动变为未分配,且占用者清空,过期时刻清零;否则该地址的状态会由占用自动变为过期,且过期时刻清零。处于未分配和过期状态的 IP 地址过期时刻为零,即没有过期时刻。
对于收到的报文,设其收到的时刻为 。处理细节如下:
判断接收主机是否为本机,或者为 *,若不是,则判断类型是否为 Request,若不是,则不处理; 若类型不是 Discover、Request 之一,则不处理; 若接收主机为 *,但类型不是 Discover,或接收主机是本机,但类型是 Discover,则不处理。 对于 Discover 报文,按照下述方法处理:
检查是否有占用者为发送主机的 IP 地址: 若有,则选取该 IP 地址; 若没有,则选取最小的状态为未分配的 IP 地址; 若没有,则选取最小的状态为过期的 IP 地址; 若没有,则不处理该报文,处理结束; 将该 IP 地址状态设置为待分配,占用者设置为发送主机; 若报文中过期时刻为 0 ,则设置过期时刻为 ;否则根据报文中的过期时刻和收到报文的时刻计算过期时间,判断是否超过上下限:若没有超过,则设置过期时刻为报文中的过期时刻;否则则根据超限情况设置为允许的最早或最晚的过期时刻; 向发送主机发送 Offer 报文,其中,IP 地址为选定的 IP 地址,过期时刻为所设定的过期时刻。 对于 Request 报文,按照下述方法处理:
检查接收主机是否为本机: 若不是,则找到占用者为发送主机的所有 IP 地址,对于其中状态为待分配的,将其状态设置为未分配,并清空其占用者,清零其过期时刻,处理结束; 检查报文中的 IP 地址是否在地址池内,且其占用者为发送主机,若不是,则向发送主机发送 Nak 报文,处理结束; 无论该 IP 地址的状态为何,将该 IP 地址的状态设置为占用; 与 Discover 报文相同的方法,设置 IP 地址的过期时刻; 向发送主机发送 Ack 报文。
二、测试样例样例1
输入
4 5 10 5 dhcp
16
1 a * DIS 0 0
2 a dhcp REQ 1 0
3 b a DIS 0 0
4 b * DIS 3 0
5 b * REQ 2 12
6 b dhcp REQ 2 12
7 c * DIS 0 11
8 c dhcp REQ 3 11
9 d * DIS 0 0
10 d dhcp REQ 4 20
11 a dhcp REQ 1 20
12 c dhcp REQ 3 20
13 e * DIS 0 0
14 e dhcp REQ 2 0
15 b dhcp REQ 2 25
16 b * DIS 0 0
输出
dhcp a OFR 1 6
dhcp a ACK 1 7
dhcp b OFR 2 9
dhcp b ACK 2 12
dhcp c OFR 3 12
dhcp c ACK 3 13
dhcp d OFR 4 14
dhcp d ACK 4 20
dhcp a ACK 1 20
dhcp c ACK 3 20
dhcp e OFR 2 18
dhcp e ACK 2 19
dhcp b NAK 2 0
样例2
输入
4 70 100 50 dhcp
6
5 a * OFR 2 100
10 b * DIS 0 70
15 b dhcp2 REQ 4 60
20 c * DIS 0 70
70 d * DIS 0 120
75 d dhcp REQ 1 125
输出
dhcp b OFR 1 70
dhcp c OFR 1 70
dhcp d OFR 1 120
dhcp d ACK 1 125
三、代码实现
#include
using namespace std;
typedef long long ll;
struct IP
{
ll state;//0---未分配,1---待分配,2---占用,3---过期
string occ_host;
ll ip_out;
}ip[10005];
//N:地址池大小
//t_def:默认过期时间
//t_max、t_min:过期时间的上下限
//H:本机名称
ll N,n,t_def,t_max,t_min;
string H;
ll rec_time,ip_ads,time_out;
string send_host,rec_host,type;
ll search_ip()
{
for(ll i=1;i
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?