import java.io.*;
import java.util.*;
class Server
{
class Address implements Comparable<Address>
{
/**
* 0 = unassigned
* 1 = waiting for assignment
* 2 = have
* 3 = outdate
**/
int state;
int ID;
int outdate;
String user;
public Address(int ID)
{
this.ID = ID;
this.state = 0;
this.outdate = 0;
this.user = null;
}
public int compareTo(Address that)
{
if (this.state == that.state)
{
return this.ID - that.ID;
}
if (this.state == 0)
{
return -1;
}
if (this.state == 3)
{
return -1;
}
return 0;
}
}
private int N;
private int Tdef;
private int Tmax;
private int Tmin;
private String H;
private Map<String, Integer> map; // check if given IP_address
private Address[] poor;
public Server(int N, int Tdef, int Tmax, int Tmin, String H)
{
this.N = N;
this.Tdef = Tdef;
this.Tmax = Tmax;
this.Tmin = Tmin;
this.H = H;
this.map = new HashMap<>();
this.poor = new Address[N + 1];
for (int i = 1; i <= N; i++)
{
poor[i] = new Address(i);
}
}
private int updatePoor(int t)
{
for (int i = 1; i <= N; i++)
{
Address address = poor[i];
if (address.outdate == t)
{
if (address.state == 1)
{
address.state = 0;
map.remove(address.user);
address.user = null;
}
else if (address.state == 2)
{
address.state = 3;
}
address.outdate = 0;
}
}
for (int i = 1; i <= N; i++)
{
Address address = poor[i];
if (address.state == 0)
{
return i;
}
}
for (int i = 1; i <= N; i++)
{
Address address = poor[i];
if (address.state == 3)
{
return i;
}
}
return 0;
}
public String handle_discover(int t, String host, int out_date)
{
// update poor !!
int IP_address = updatePoor(t);
if (map.containsKey(host))
{
IP_address = map.get(host);
}
else if (IP_address != 0)
{
Address address = poor[IP_address];
if (address.state == 0 || address.state == 3)
{
IP_address = address.ID;
address.state = 1;
address.user = host;
map.put(host, IP_address);
}
else
{
return null;
}
}
else
{
return null;
}
if (out_date == 0)
{
out_date = t + Tdef;
}
else if (out_date < t + Tmin)
{
out_date = t + Tmin;
}
else if (out_date > t + Tmax)
{
out_date = t + Tmax;
}
return packet(host, "OFR", IP_address, out_date);
}
public String handle_request(int t, String host, int IP_address, int out_date)
{
// update poor !!
int flag = updatePoor(t);
if (IP_address < 1 || IP_address > N)
{
return packet(host, "NAK", IP_address, 0);
}
if (!map.containsKey(host))
{
return packet(host, "NAK", IP_address, 0);
}
/*
if (t == 15)
{
System.out.println(map.get(host) + " " + IP_address);
}
*/
if (!map.get(host).equals(IP_address) && flag == 0)
{
return null;
}
Address address = poor[IP_address];
address.state = 2;
if (out_date == 0)
{
out_date = t + Tdef;
}
else if (out_date < t + Tmin)
{
out_date = t + Tmin;
}
else if (out_date > t + Tmax)
{
out_date = t + Tmax;
}
address.outdate = out_date;
return packet(host, "ACK", IP_address, out_date);
}
public void clear(String host)
{
if (map.containsKey(host))
{
int IP_address = map.get(host);
Address address = poor[IP_address];
if (address.state == 1)
{
address.state = 0;
address.user = null;
address.outdate = 0;
}
}
}
private String packet(String host, String packet_type, int IP_address, int out_date)
{
return H + " " + host + " " + packet_type + " " + IP_address + " " + out_date;
}
}
class Main {
public Main() throws IOException
{
BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
StringTokenizer st = new StringTokenizer(f.readLine());
int N = Integer.parseInt(st.nextToken());
int Tdef = Integer.parseInt(st.nextToken());
int Tmax = Integer.parseInt(st.nextToken());
int Tmin = Integer.parseInt(st.nextToken());
String H = st.nextToken();
Server server = new Server(N, Tdef, Tmax, Tmin, H);
int n = Integer.parseInt(f.readLine()); // n packets
while ((n--) > 0)
{
st = new StringTokenizer(f.readLine());
int t = Integer.parseInt(st.nextToken());
String sent_host = st.nextToken();
String recived_host = st.nextToken();
String packet_type = st.nextToken();
int IP_address = Integer.parseInt(st.nextToken());
int out_date = Integer.parseInt(st.nextToken());
String result = null;
// handle Discover packet
if (recived_host.equals("*") && packet_type.equals("DIS"))
{
result = server.handle_discover(t, sent_host, out_date);
}
// handle Requset packet
else if (recived_host.equals(H) && packet_type.equals("REQ"))
{
result = server.handle_request(t, sent_host, IP_address, out_date);
}
else if (packet_type.equals("REQ"))
{
server.clear(sent_host);
}
if (result != null)
{
// out.print(16 - n + " ");
out.println(result);
}
}
out.close();
f.close();
}
public static void main(String[] args) throws IOException
{
new Main();
}
}
[Java] 202104-3 DHCP服务器 (60分 debugging)
最新推荐文章于 2022-06-04 23:18:24 发布