From 462b376eeef8d3c3acb264f50fcba7857167353a Mon Sep 17 00:00:00 2001 From: Louis Date: Thu, 23 Jan 2020 17:21:23 +0100 Subject: [PATCH] Add send + receive methods --- src/protocolP2P/FileList.java | 4 ++- src/protocolP2P/FilePart.java | 4 ++- src/protocolP2P/Payload.java | 9 ++++- src/protocolP2P/ProtocolP2PDatagram.java | 42 +++++++++++++++++++----- 4 files changed, 47 insertions(+), 12 deletions(-) diff --git a/src/protocolP2P/FileList.java b/src/protocolP2P/FileList.java index 65c824f..6734f38 100644 --- a/src/protocolP2P/FileList.java +++ b/src/protocolP2P/FileList.java @@ -2,6 +2,7 @@ package protocolP2P; import java.util.Arrays; import protocolP2P.Payload; import protocolP2P.RequestResponseCode; +import exception.TransmissionError; import exception.ProtocolError; import exception.InternalError; import exception.SizeError; @@ -36,8 +37,9 @@ public class FileList extends Payload { * @throws SizeError * @throws InternalError * @throws ProtocolError + * @throws TransmissionError */ - protected FileList(byte[] datagram) throws SizeError, ProtocolError, InternalError { + protected FileList(byte[] datagram) throws TransmissionError, SizeError, ProtocolError, InternalError { super(datagram); /* assert to help debugging */ assert requestResponseCode == RequestResponseCode.LIST_RESPONSE : "FileList subclass is incompatible with this datagram, request/response code must be checked before using this constructor"; diff --git a/src/protocolP2P/FilePart.java b/src/protocolP2P/FilePart.java index d6d6d2c..1dd89ce 100644 --- a/src/protocolP2P/FilePart.java +++ b/src/protocolP2P/FilePart.java @@ -4,6 +4,7 @@ import protocolP2P.RequestResponseCode; import exception.ProtocolError; import exception.InternalError; import exception.SizeError; +import exception.TransmissionError; import tools.BytesArrayTools; import java.util.Arrays; import java.io.UnsupportedEncodingException; @@ -49,8 +50,9 @@ public class FilePart extends Payload { * @param datagram the full datagram received * @throws SizeError * @throws InternalError + * @throws TransmissionError */ - protected FilePart(byte[] datagram) throws SizeError, ProtocolError, InternalError { + protected FilePart(byte[] datagram) throws TransmissionError, SizeError, ProtocolError, InternalError { super(datagram); /* assert to help debugging */ assert requestResponseCode == RequestResponseCode.LOAD_RESPONSE : "FilePart subclass is incompatible with this datagram, request/response code must be checked before using this constructor"; diff --git a/src/protocolP2P/Payload.java b/src/protocolP2P/Payload.java index ce55f38..f09010c 100644 --- a/src/protocolP2P/Payload.java +++ b/src/protocolP2P/Payload.java @@ -4,6 +4,7 @@ import protocolP2P.FilePart; import protocolP2P.FileList; import exception.ProtocolError; import exception.InternalError; +import exception.TransmissionError; import exception.SizeError; import tools.BytesArrayTools; /** Representation of payload. If payload has a size, use subclasses instead. @@ -34,9 +35,15 @@ public class Payload { * @param datagram the full datagram received * @throws ProtocolError * @throws InternalError + * @throws TransmissionError + * @throws SizeError */ - protected Payload(byte[] datagram) throws ProtocolError, InternalError { + protected Payload(byte[] datagram) throws SizeError, ProtocolError, InternalError, TransmissionError { /* asserts to help debugging */ + assert getPayloadSize(datagram) + 8 <= datagram.length : "Payload is truncated"; + if (datagram.length < getPayloadSize(datagram) + 8) { + throw new TransmissionError(); + } assert RequestResponseCode.fromCode(datagram[RequestResponseCode.RRCODE_POSITION]) != RequestResponseCode.LIST_RESPONSE || (this instanceof FileList) : "LIST_RESPONSE must use FilePart class"; assert RequestResponseCode.fromCode(datagram[RequestResponseCode.RRCODE_POSITION]) != RequestResponseCode.LOAD_RESPONSE || (this instanceof FilePart) : "LOAD_RESPONSE must use FileList class"; requestResponseCode = RequestResponseCode.fromCode(datagram[RequestResponseCode.RRCODE_POSITION]); diff --git a/src/protocolP2P/ProtocolP2PDatagram.java b/src/protocolP2P/ProtocolP2PDatagram.java index a259028..730eac3 100644 --- a/src/protocolP2P/ProtocolP2PDatagram.java +++ b/src/protocolP2P/ProtocolP2PDatagram.java @@ -3,12 +3,16 @@ import exception.ProtocolError; import exception.VersionError; import exception.SizeError; import exception.InternalError; +import exception.TransmissionError; import protocolP2P.Payload; import protocolP2P.RequestResponseCode; import java.util.ArrayList; import java.lang.Byte; import java.net.DatagramPacket; import java.net.DatagramSocket; +import java.net.InetAddress; +import java.io.IOException; +import java.net.UnknownHostException; /** Representation of datagram. * @author Louis Royer @@ -30,41 +34,61 @@ public class ProtocolP2PDatagram { this.payload = payload; } - /** Send datagram on socket - * @param socket DatagramSocket used to send datagram + /** Send datagram on socket (from client) + * @param socket DatagramSocket used to send datagram. + * @param host host to send datagram (null if this is a response) + * @param port port to send datagram (null if this is a response) * @throws InternalError + * @throws UnknownHostException + * @throws IOException */ - public void send(DatagramSocket socket) throws InternalError { - //TODO + public void send(DatagramSocket socket, String host, int port) throws InternalError, UnknownHostException, IOException { + InetAddress dst = InetAddress.getByName(host); byte[] datagram = toDatagram(); // generate DatagramPacket + DatagramPacket datagramPacket = new DatagramPacket(datagram, datagram.length, dst, port); // send it + socket.send(datagramPacket); + } + + /** Send datagram on socket (from server, as a response) + * @param socket DatagramSocket used to send datagram. + * @throws InternalError + * @throws IOException + */ + public void send(DatagramSocket socket) throws InternalError, IOException { + byte[] datagram = toDatagram(); + // generate DatagramPacket + DatagramPacket datagramPacket = new DatagramPacket(datagram, datagram.length); + socket.send(datagramPacket); } /** Receive datagram on socket * @param socket DatagramSocket used to receive datagram * @return payload of the datagram + * @throws TransmissionError * @throws ProtocolError * @throws VersionError * @throws InternalError * @throws SizeError */ - public static Payload receive(DatagramSocket socket) throws ProtocolError, VersionError, InternalError, SizeError { - //TODO + public static Payload receive(DatagramSocket socket) throws TransmissionError, ProtocolError, VersionError, InternalError, SizeError { // reception - byte[] datagram = new byte[5]; + byte[] datagram = new byte[4096]; + DatagramPacket reception = new DatagramPacket(datagram, datagram.length); // contruction ProtocolP2PDatagram p = new ProtocolP2PDatagram(datagram); return p.getPayload(); } /** Private constructor with datagram as byte[] parameter (typically used when receiving datagram). * @param datagram the full datagram received + * @throws TransmissionError * @throws ProtocolError * @throws VersionError * @throws InternalError * @throws SizeError */ - private ProtocolP2PDatagram(byte[] datagram) throws ProtocolError, VersionError, InternalError, SizeError { + private ProtocolP2PDatagram(byte[] datagram) throws TransmissionError, ProtocolError, VersionError, InternalError, SizeError { // unwrap version version = datagram[VERSION_POSITON]; checkProtocolVersion(); // this can throw VersionError @@ -77,7 +101,7 @@ public class ProtocolP2PDatagram { payload = (Payload) new FilePart(datagram); break; default: - payload = new Payload(datagram); + payload = new Payload(datagram); // this can throw TransmissionError break; } }