From 5fa160d98d7a90963f42b86fdb05274743dbc359 Mon Sep 17 00:00:00 2001 From: Louis Royer Date: Fri, 27 Mar 2020 16:59:17 +0100 Subject: [PATCH] Add classes for ratio --- doc/protocol.md | 5 +- src/protocolP2P/RatioRequest.java | 77 ++++++++++++++++++++ src/protocolP2P/RatioResponse.java | 106 +++++++++++++++++++++++++++ src/protocolP2P/Register.java | 4 +- src/protocolP2P/Unregister.java | 4 +- src/protocolP2P/UpdateRatio.java | 112 +++++++++++++++++++++++++++++ 6 files changed, 302 insertions(+), 6 deletions(-) create mode 100644 src/protocolP2P/RatioRequest.java create mode 100644 src/protocolP2P/RatioResponse.java create mode 100644 src/protocolP2P/UpdateRatio.java diff --git a/doc/protocol.md b/doc/protocol.md index 997adb0..045382c 100644 --- a/doc/protocol.md +++ b/doc/protocol.md @@ -171,15 +171,16 @@ Possible responses: Ratio Response, or Unknown Host #### Ratio Response Contains: ```text -2 bytes: port -? bytes: hostname followed by \n 8 bytes: total sent bytes 8 bytes: total received bytes +2 bytes: port +? bytes: hostname ``` #### Update Ratio Contains: ```text +8 bytes: bytes sent by the server 2 bytes: server port 2 bytes: client* port ? bytes: server hostname followed by \n diff --git a/src/protocolP2P/RatioRequest.java b/src/protocolP2P/RatioRequest.java new file mode 100644 index 0000000..87e76bf --- /dev/null +++ b/src/protocolP2P/RatioRequest.java @@ -0,0 +1,77 @@ +package protocolP2P; +import protocolP2P.Payload; +import tools.HostItem; +import tools.BytesArrayTools; +import localException.SizeError; +import localException.InternalError; +import localException.TransmissionError; +import localException.ProtocolError; + +/** Representation of payload for ratio request. + * @author Louis Royer + * @author Flavien Haas + * @author JS Auge + * @version 1.0 + */ +public class RatioRequest extends Payload { + private HostItem hostItem; + private static final int HOSTNAME_START_POSITION = PAYLOAD_START_POSITION + 2; + + /** Constructor with hostItem (typically used by client/server) + * @param hostItem Host to get ratio of. + * @throws InternalError + */ + public RatioRequest(HostItem hostItem) throws InternalError { + super(RequestResponseCode.RATIO_REQUEST); + this.hostItem = hostItem; + } + + /** Constructor (typically used by tracker) with a byte[] parameter containing the Packet received. + * @param packet the full Packet received + * @throws SizeError + * @throws InternalError + * @throws ProtocolError + * @throws TransmissionError + */ + protected RatioRequest(byte[] packet) throws SizeError, ProtocolError, InternalError, TransmissionError { + super(packet); + int size = getPayloadSize(packet); + int port = BytesArrayTools.readInt16Bits(packet, PAYLOAD_START_POSITION); + String hostname = BytesArrayTools.readString(packet, HOSTNAME_START_POSITION, size - HOSTNAME_START_POSITION + PAYLOAD_START_POSITION); + hostItem = new HostItem(hostname, port); + } + + /** Returns a byte[] containing Packet with padding. + * This Packet is still incomplete and should not be send directly. + * ProtocolP2PPacket will use this method to generate the complete Packet. + * @return Packet with padding + * @throws InternalError + */ + protected byte[] toPacket() throws InternalError { + String hostname = hostItem.getHostname(); + // compute total size + int size = 1 + HOSTNAME_START_POSITION + hostname.length(); + byte[] packet = new byte[size]; // java initialize all to zero + // set request/response code + packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue; + // set Payload size + setPayloadSize(size - PAYLOAD_START_POSITION, packet); + // write port to Packet + try { + BytesArrayTools.write16Bits(packet, PAYLOAD_START_POSITION, hostItem.getPort()); + } catch (SizeError e) { + throw new InternalError(); + } + // write hostname to Packet + BytesArrayTools.write(packet, hostname, HOSTNAME_START_POSITION); + return packet; + } + + /** HostItem getter. + * @return hostItem + */ + public HostItem getHostItem() { + return hostItem; + } + +} diff --git a/src/protocolP2P/RatioResponse.java b/src/protocolP2P/RatioResponse.java new file mode 100644 index 0000000..05e07ca --- /dev/null +++ b/src/protocolP2P/RatioResponse.java @@ -0,0 +1,106 @@ +package protocolP2P; +import protocolP2P.Payload; +import tools.HostItem; +import tools.BytesArrayTools; +import localException.SizeError; +import localException.InternalError; +import localException.TransmissionError; +import localException.ProtocolError; + +/** Representation of payload for ratio response. + * @author Louis Royer + * @author Flavien Haas + * @author JS Auge + * @version 1.0 + */ +public class RatioResponse extends Payload { + private HostItem hostItem; + private long totalUp; + private long totalDown; + private static final int TOTAL_UP_START_POSITION = PAYLOAD_START_POSITION; + private static final int TOTAL_DOWN_START_POSITION = TOTAL_UP_START_POSITION + 8; + private static final int PORT_START_POSITION = TOTAL_DOWN_START_POSITION + 8; + private static final int HOSTNAME_START_POSITION = PORT_START_POSITION + 2; + + /** Constructor with hostItem (typically used by tracker) + * @param hostItem Host to get ratio of. + * @param totalUp total bytes uploaded + * @param totalDown total bytes downloaded + * @throws InternalError + */ + public RatioResponse(HostItem hostItem, long totalUp, long totalDown) throws InternalError { + super(RequestResponseCode.RATIO_RESPONSE); + this.hostItem = hostItem; + this.totalUp = totalUp; + this.totalDown = totalDown; + } + + /** Constructor (typically used by client/server) with a byte[] parameter containing the Packet received. + * @param packet the full Packet received + * @throws SizeError + * @throws InternalError + * @throws ProtocolError + * @throws TransmissionError + */ + protected RatioResponse(byte[] packet) throws SizeError, ProtocolError, InternalError, TransmissionError { + super(packet); + int size = getPayloadSize(packet); + totalUp = BytesArrayTools.readLong(packet, TOTAL_UP_START_POSITION); + totalDown = BytesArrayTools.readLong(packet, TOTAL_DOWN_START_POSITION); + int port = BytesArrayTools.readInt16Bits(packet, PORT_START_POSITION); + String hostname = BytesArrayTools.readString(packet, HOSTNAME_START_POSITION, size - HOSTNAME_START_POSITION + PAYLOAD_START_POSITION); + hostItem = new HostItem(hostname, port); + } + + /** Returns a byte[] containing Packet with padding. + * This Packet is still incomplete and should not be send directly. + * ProtocolP2PPacket will use this method to generate the complete Packet. + * @return Packet with padding + * @throws InternalError + */ + protected byte[] toPacket() throws InternalError { + String hostname = hostItem.getHostname(); + // compute total size + int size = 1 + HOSTNAME_START_POSITION + hostname.length(); + byte[] packet = new byte[size]; // java initialize all to zero + // set request/response code + packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue; + // set Payload size + setPayloadSize(size - PAYLOAD_START_POSITION, packet); + // write totalUp + BytesArrayTools.write(packet, TOTAL_UP_START_POSITION, totalUp); + // write totalDown + BytesArrayTools.write(packet, TOTAL_DOWN_START_POSITION, totalDown); + // write port to Packet + try { + BytesArrayTools.write16Bits(packet, PORT_START_POSITION, hostItem.getPort()); + } catch (SizeError e) { + throw new InternalError(); + } + // write hostname to Packet + BytesArrayTools.write(packet, hostname, HOSTNAME_START_POSITION); + return packet; + } + + /** HostItem getter. + * @return hostItem + */ + public HostItem getHostItem() { + return hostItem; + } + + /** totalUp getter. + * @return totalUp + */ + public long getTotalUp() { + return totalUp; + } + + /** totalDown getter. + * @return totalDown + */ + public long getTotalDown() { + return totalDown; + } + +} diff --git a/src/protocolP2P/Register.java b/src/protocolP2P/Register.java index 790ac2b..4f49022 100644 --- a/src/protocolP2P/Register.java +++ b/src/protocolP2P/Register.java @@ -50,8 +50,8 @@ public class Register extends Payload { protected byte[] toPacket() throws InternalError { String hostname = hostItem.getHostname(); // compute total size - int size = HOSTNAME_START_POSITION + hostname.length(); - byte[] packet = new byte[size + 1]; // java initialize all to zero + int size = 1 + HOSTNAME_START_POSITION + hostname.length(); + byte[] packet = new byte[size]; // java initialize all to zero // set request/response code packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue; // set Payload size diff --git a/src/protocolP2P/Unregister.java b/src/protocolP2P/Unregister.java index 8307a5b..35e34a8 100644 --- a/src/protocolP2P/Unregister.java +++ b/src/protocolP2P/Unregister.java @@ -50,8 +50,8 @@ public class Unregister extends Payload { protected byte[] toPacket() throws InternalError { String hostname = hostItem.getHostname(); // compute total size - int size = HOSTNAME_START_POSITION + hostname.length(); - byte[] packet = new byte[size + 1]; // java initialize all to zero + int size = 1 + HOSTNAME_START_POSITION + hostname.length(); + byte[] packet = new byte[size]; // java initialize all to zero // set request/response code packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue; // set Payload size diff --git a/src/protocolP2P/UpdateRatio.java b/src/protocolP2P/UpdateRatio.java new file mode 100644 index 0000000..b373623 --- /dev/null +++ b/src/protocolP2P/UpdateRatio.java @@ -0,0 +1,112 @@ +package protocolP2P; +import protocolP2P.Payload; +import tools.HostItem; +import tools.BytesArrayTools; +import localException.SizeError; +import localException.InternalError; +import localException.TransmissionError; +import localException.ProtocolError; + +/** Representation of payload for update ratio. + * @author Louis Royer + * @author Flavien Haas + * @author JS Auge + * @version 1.0 + */ +public class UpdateRatio extends Payload { + private HostItem client; + private HostItem server; + private long dataSize; + private static final int DATA_SIZE_POSITION = PAYLOAD_START_POSITION; + private static final int SERVER_PORT_START_POSITION = DATA_SIZE_POSITION + 8; + private static final int CLIENT_PORT_START_POSITION = SERVER_PORT_START_POSITION + 2; + private static final int HOSTNAMES_START_POSITION = CLIENT_PORT_START_POSITION + 2; + + /** Constructor with hostItem (typically used by client) + * @param client HostItem of the client application. + * @param server HostItem of the server application. + * @param dataSize size of data sent. + * @throws InternalError + */ + public UpdateRatio(HostItem client, HostItem server, long dataSize) throws InternalError { + super(RequestResponseCode.UPDATE_RATIO); + this.client = client; + this.server = server; + this.dataSize = dataSize; + } + + /** Constructor (typically used by tracker) with a byte[] parameter containing the Packet received. + * @param packet the full Packet received + * @throws SizeError + * @throws InternalError + * @throws ProtocolError + * @throws TransmissionError + */ + protected UpdateRatio(byte[] packet) throws SizeError, ProtocolError, InternalError, TransmissionError { + super(packet); + int size = getPayloadSize(packet); + dataSize = BytesArrayTools.readLong(packet, DATA_SIZE_POSITION); + int portServer = BytesArrayTools.readInt16Bits(packet, SERVER_PORT_START_POSITION); + int portClient = BytesArrayTools.readInt16Bits(packet, CLIENT_PORT_START_POSITION); + String[] hostnames = BytesArrayTools.readStringArray(packet, HOSTNAMES_START_POSITION, size - HOSTNAMES_START_POSITION + PAYLOAD_START_POSITION, "\n"); + server = new HostItem(hostnames[0], portServer); + client = new HostItem(hostnames[1], portClient); + } + + /** Returns a byte[] containing Packet with padding. + * This Packet is still incomplete and should not be send directly. + * ProtocolP2PPacket will use this method to generate the complete Packet. + * @return Packet with padding + * @throws InternalError + */ + protected byte[] toPacket() throws InternalError { + String[] hostnames = { server.getHostname(), client.getHostname()}; + // compute total size + int size = 1 + HOSTNAMES_START_POSITION + BytesArrayTools.computeStringArraySize(hostnames, "\n"); + byte[] packet = new byte[size]; // java initialize all to zero + // set request/response code + packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue; + // set Payload size + setPayloadSize(size - PAYLOAD_START_POSITION, packet); + // write dataSize + BytesArrayTools.write(packet, DATA_SIZE_POSITION, dataSize); + // write server port to Packet + try { + BytesArrayTools.write16Bits(packet, SERVER_PORT_START_POSITION, server.getPort()); + } catch (SizeError e) { + throw new InternalError(); + } + // write client port to Packet + try { + BytesArrayTools.write16Bits(packet, CLIENT_PORT_START_POSITION, client.getPort()); + } catch (SizeError e) { + throw new InternalError(); + } + // write hostnames to Packet + BytesArrayTools.write(packet, hostnames, HOSTNAMES_START_POSITION, "\n"); + return packet; + } + + /** Client getter. + * @return client + */ + public HostItem getClient() { + return client; + } + + /** Server getter + * @return server + */ + public HostItem getServer() { + return server; + } + + /** dataSize getter. + * @return dataSize + */ + public long getDataSize() { + return dataSize; + } + + +}