package dslab.monitoring; import dslab.protocol.Message; import dslab.util.TransferServerConfig; import java.io.Closeable; import java.io.IOException; import java.net.*; import java.util.logging.Logger; import static java.util.logging.Level.SEVERE; public class MonitoringClient implements Closeable { private static final Logger LOG = Logger.getLogger(MonitoringClient.class.getSimpleName()); private final DatagramSocket socket; private final InetAddress monitoringAddress; private final int monitoringPort; private final String MY_IP; private final int MY_PORT; /** * The client side representation of the monitoring server. This class essentially * wraps the transfer server end of the UDP channel between the transfer server and the * monitoring server */ public MonitoringClient(TransferServerConfig config) throws SocketException, UnknownHostException { socket = new DatagramSocket(); //Get these values in the constructor so we fail fast monitoringAddress = InetAddress.getByName(config.monitoringHost()); monitoringPort = config.monitoringPort(); MY_IP = InetAddress.getLocalHost().getHostAddress(); MY_PORT = config.tcpPort(); } /** * Reports sent messages to the transfer server. The assignment doesn't specify if a message with * two recipients counts as two messages or as one. If the goal is to detect abuse, as indicated * in the assignment text, then it makes more sense to count it as two; so that's what we do here * @param message to report to the monitoring server as having been sent */ public void report(Message message) { var report = MY_IP + ":" + MY_PORT + " " + message.getSender(); LOG.info("Reporting to monitoring server: " + report); byte[] buffer = report.getBytes(); var packet = new DatagramPacket(buffer, buffer.length, monitoringAddress, monitoringPort); try { //Send packet n times if the message has n recipients. This is stupid but the spec demands it for(var i = 1; i <= message.getRecipients().size(); ++i) socket.send(packet); } catch (IOException e) { LOG.log(SEVERE, "Unable to report to monitoring server", e); } } public void close() { socket.close(); } }