当前位置: 首页 > 工具软件 > dhcp4java > 使用案例 >

编程练习题(简单DHCP服务器实现)-Java集合的运用

卓学智
2023-12-01

题目描述
DHCP服务器的功能是为每一个MAC地址分配唯一的IP地址。现假设:分配的IP地址范围从 192.168.0.0 到 192.168.0.255 总共256个可用地址(以点分十进制表示)。请实现一个简易的DHCP服务器,功能如下:

分配Request:根据输入的MAC地址分配IP地址池中的IP地址:

如果对应的IP已分配并未释放,则为重复申请,直接返回对应已分配的IP地址。
如果一个MAC地址已申请过并已释放,即:当前未分配IP地址,则为再申请,优先分配最近一次曾经为其分配过的IP地址,请返回此地址。
按升序分配从未被分配过的IP地址;如果地址池中地址都已被分配过,则按升序分配已释放出来的IP地址;若可分配成功,则返回此IP地址。
若仍然无法分配成功,则返回NA。
释放Release:根据输入的MAC地址释放已分配的IP地址:

如果申请释放的对应的IP地址已分配,则释放此IP地址;
如果申请释放的对应的IP地址不存在,则不作任何事情;
解答要求
时间限制: 1000ms, 内存限制: 64MB
输入
首行为整数n, 表示其后输入的命令行数,范围[1,2000]。
之后每行为一条分配命令,格式为:命令=MAC地址

命令只有两种:REQUEST 和 RELEASE,分别表示分配和释放;
MAC地址为:12个大写英文字母或数字,如:AABBCCDDEEF1。

输出
1.REQUEST命令,输出分配结果(IP地址或NA),均为字符串形式。

注意:IP地址的各区段不设置前置 0

2.RELEASE命令,不输出任何内容。

样例
输入样例1
2
REQUEST=AABBCCDDEEF1
RELEASE=AABBCCDDEEF1
输出样例1
192.168.0.0
输入样例2
6
REQUEST=AABBCCDDEEF1
REQUEST=F2FBBCCDDEEF
RELEASE=AABBCCDDEEF1
RELEASE=F2FBBCCDDEEF
REQUEST=333333333333
REQUEST=F2FBBCCDDEEF
输出样例2
192.168.0.0
192.168.0.1
192.168.0.2
192.168.0.1
提示
REQUEST=AABBCCDDEEF1 按升序分配从未使用过的IP,为192.168.0.0
REQUEST=F2FBBCCDDEEF 按升序分配从未使用过的IP,为192.168.0.1
RELEASE=AABBCCDDEEF1 释放IP 192.168.0.0。
RELEASE=F2FBBCCDDEEF 释放IP 192.168.0.1。
REQUEST=333333333333 按升序分配从未使用过的IP,为192.168.0.2
REQUEST=F2FBBCCDDEEF 该MAC地址再申请,优先分配最近一次曾经为其分配过的IP,为192.168.0.1

代码实现:

import java.nio.charset.StandardCharsets;
import java.util.*;
class DHCP{
    private List<Integer> neverUses;
    private Map<Integer,Boolean> isUsed;
    private List<Integer> releases;
    private Map<String,Integer> tables;
    private Map<String,Integer> records;
    public DHCP() {
        this.neverUses = new ArrayList<>();
        this.isUsed = new HashMap<>();
        this.releases = new ArrayList<>();
        this.records=new HashMap<>();
        this.tables = new HashMap<>();
        for(int i=0;i<=255;i++){
            this.neverUses.add(i);
            this.isUsed.put(i,false);
        }
    }
    /**
     * 分配:
     * 如果有记录,直接返回
     * 如果有释放的记录,如果最近释放的ip地址没有被使用,则分配最近释放的IP地址
     * 如果上面不满足,按照升序分配未分配的地址,
     * 所有地址都被分配过了,则按照升序分配已经释放的地址。
     * 若依旧无法分配,则输出NA
     */
    public String request(String mac) {
        if(this.tables.get(mac)!=null)
            return this.tables.get(mac).toString();
        if(this.records.get(mac)!=null){
            Integer ip=this.records.get(mac);
            if(!this.isUsed.get(ip)){
                this.isUsed.put(ip,true);
                this.tables.put(mac, ip);
                this.releases.remove(ip);
                return ip.toString();
            }
        }
        if (this.neverUses.size() > 0) {
            Integer ip=this.neverUses.get(0);
            this.records.put(mac, ip);
            this.isUsed.put(ip,true);
            this.tables.put(mac,ip);
            this.neverUses.remove(0);
            return ip.toString();
        }
        if (this.releases.size() > 0) {
            int k=0;
            for (int i = 0; i < this.releases.size(); i++) {
                if(this.releases.get(k)>this.releases.get(i)){
                    k=i;
                }
            }
            Integer ip = this.releases.get(k);
            this.releases.remove(k);
            this.isUsed.put(ip, true);
            this.records.put(mac,ip);
            this.tables.put(mac, ip);
            return ip.toString();
        }
        return "NA";
    }

    public void release(String mac) {
        if(this.tables.get(mac)!=null){
            Integer ip = this.tables.get(mac);
            this.isUsed.put(ip, false);
            this.releases.add(ip);
            this.tables.remove(mac);
        }
    }
}
public class Main {
    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in, StandardCharsets.UTF_8.name());
        DHCP dhcp = new DHCP();
        int operationCnt = cin.nextInt();
        for (int i = 0; i < operationCnt; i++) {
            String[] operation = cin.next().split("=");
            if ("REQUEST".equals(operation[0])) {
                String value = dhcp.request(operation[1]);
                if(value.equals("NA")) System.out.println(value);
                else System.out.println("192.168.0."+dhcp.request(operation[1]));
            } else {
                dhcp.release(operation[1]);
            }
        }
        cin.close();
    }
}

 类似资料: