Fix #41
flavien's git/Projet_JAVA_P2P_STRI2A/pipeline/pr-etape5 This commit looks good Details

pull/86/head
Louis Royer 5 years ago
parent 77655cb828
commit c81f5d2e5a

@ -22,6 +22,7 @@ x bytes: [(bytes 8-?): PAYLOAD]
- `UNREGISTER` (0x05) - `UNREGISTER` (0x05)
- `RATIO` (0x06) - `RATIO` (0x06)
- `UPDATE RATIO` (0x07) - `UPDATE RATIO` (0x07)
- `SIZE` (0x08)
- RESPONSES (msb is 1): - RESPONSES (msb is 1):
- `LIST` (0x80) - `LIST` (0x80)
@ -30,6 +31,7 @@ x bytes: [(bytes 8-?): PAYLOAD]
- `DISCOVER` (0x83) - `DISCOVER` (0x83)
- `RATIO` (0x86) - `RATIO` (0x86)
- `DENIED` (0x87) - `DENIED` (0x87)
- `SIZE` (0x88)
- `VERSION ERROR` (0xC0) - `VERSION ERROR` (0xC0)
- `PROTOCOL ERROR` (0xC1) - `PROTOCOL ERROR` (0xC1)
- `INTERNAL ERROR` (0xC2) - `INTERNAL ERROR` (0xC2)
@ -59,7 +61,6 @@ Payload contains
```text ```text
8 bytes: [(bytes 8-15): OFFSET OF FILE CONTENT IN BYTES] 8 bytes: [(bytes 8-15): OFFSET OF FILE CONTENT IN BYTES]
8 bytes: [(bytes 16-23): TOTAL FILESIZE]
4 bytes: [(bytes 24-27): FILENAME SIZE] (cannot be > to PAYLOAD_SIZE - 20 or be zero) 4 bytes: [(bytes 24-27): FILENAME SIZE] (cannot be > to PAYLOAD_SIZE - 20 or be zero)
y bytes: [<FILENAME>] y bytes: [<FILENAME>]
z bytes: [PARTIAL CONTENT] z bytes: [PARTIAL CONTENT]
@ -78,6 +79,23 @@ y bytes: [<FILENAME>]
``` ```
Possible responses: Load Response, or Denied Possible responses: Load Response, or Denied
### Size
#### Size request
Payload contains
```text
? bytes: filename
```
Possible responses: Size response, EmptyFile or NotFound
#### Size response
Payload contains
```text
8 bytes: file size
? bytes: filename
```
### Hash ### Hash
#### Hash request #### Hash request
Get hash of a file. Payload contains Get hash of a file. Payload contains

@ -29,7 +29,8 @@ import protocolP2P.HashResponse;
import protocolP2P.HashRequest; import protocolP2P.HashRequest;
import protocolP2P.Payload; import protocolP2P.Payload;
import protocolP2P.FilePart; import protocolP2P.FilePart;
import protocolP2P.LoadRequest; import protocolP2P.SizeRequest;
import protocolP2P.SizeResponse;
import protocolP2P.ProtocolP2PPacket; import protocolP2P.ProtocolP2PPacket;
import clientP2P.ClientDownloadPart; import clientP2P.ClientDownloadPart;
import tools.HostItem; import tools.HostItem;
@ -291,39 +292,22 @@ public abstract class ClientDownload extends ServeErrors implements Runnable {
* @throws InternalError * @throws InternalError
*/ */
protected void setSize() throws InternalError { protected void setSize() throws InternalError {
ProtocolP2PPacket<?> d = createProtocolP2PPacket(new LoadRequest(filename, 0, MAX_PARTIAL_SIZE, client)); ProtocolP2PPacket<?> d = createProtocolP2PPacket(new SizeRequest(filename));
try { try {
d.sendRequest(getHostItemSocket(hostList.get(0))); d.sendRequest(getHostItemSocket(hostList.get(0)));
try { try {
Payload p = d.receiveResponse().getPayload(); Payload p = d.receiveResponse().getPayload();
assert p instanceof FilePart : "This payload must be instance of FilePart"; assert p instanceof SizeResponse : "This payload must be instance of SizeResponse";
if (!(p instanceof FilePart)) { if (!(p instanceof SizeResponse)) {
System.err.println("Error: cannot get size.");
writeLog("cannot get size.", LogLevel.Error); writeLog("cannot get size.", LogLevel.Error);
throw new InternalError(); throw new InternalError();
} else { } else {
FilePart fp = (FilePart)p; SizeResponse fp = (SizeResponse)p;
if (!fp.getFilename().equals(filename)) { if (!fp.getFilename().equals(filename)) {
System.err.println("Error: wrong file received: `" + fp.getFilename() + "`"); writeLog("wrong file size received: `" + fp.getFilename() + "`", LogLevel.Error);
writeLog("wrong file received: `" + fp.getFilename() + "`", LogLevel.Error);
throw new ProtocolError(); throw new ProtocolError();
} }
if (fp.getOffset() == 0) { size = fp.getTotalSize();
try {
Files.write(new File(partsSubdir + filename + "_0.part").toPath(), fp.getPartialContent());
} catch (IOException e) {
System.err.println("Error: cannot write file (" + partsSubdir + filename + "_0.part)");
writeLog("cannot write file (" + partsSubdir + filename + "_0.part)", LogLevel.Error);
}
size = fp.getTotalSize();
if (fp.getPartialContent().length == size) {
stop = true;
}
} else {
System.err.println("Error: wrong file part received.");
writeLog("wrong file part received.", LogLevel.Error);
throw new InternalError();
}
} }
} catch (EmptyDirectory e) { } catch (EmptyDirectory e) {
System.err.println("Error: empty directory."); System.err.println("Error: empty directory.");
@ -395,7 +379,7 @@ public abstract class ClientDownload extends ServeErrors implements Runnable {
// Add tasks // Add tasks
if (!stop) { if (!stop) {
for(long i=MAX_PARTIAL_SIZE; i<size;i+=MAX_PARTIAL_SIZE) { for(long i=0; i<size;i+=MAX_PARTIAL_SIZE) {
offsetsToAsk.add(Long.valueOf(i)); offsetsToAsk.add(Long.valueOf(i));
} }
writeLog("Adding tasks: done", LogLevel.Info); writeLog("Adding tasks: done", LogLevel.Info);

@ -50,7 +50,7 @@ public class DiscoverRequest extends Payload {
*/ */
protected byte[] toPacket() throws InternalError { protected byte[] toPacket() throws InternalError {
// compute total size // compute total size
int size = 1 + PAYLOAD_START_POSITION + filename.length(); int size = PAYLOAD_START_POSITION + filename.length();
byte[] packet = new byte[size]; // java initialize all to zero byte[] packet = new byte[size]; // java initialize all to zero
// set request/response code // set request/response code
packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue; packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue;

@ -74,7 +74,7 @@ public class DiscoverResponse extends Payload {
hostListSize += (2 + hostItem.getHostname().length() + 1); hostListSize += (2 + hostItem.getHostname().length() + 1);
} }
// compute total size // compute total size
int size = 1 + FILENAME_POSITION + filename.length() + hostListSize; int size = FILENAME_POSITION + filename.length() + hostListSize;
byte[] packet = new byte[size]; // java initialize all to zero byte[] packet = new byte[size]; // java initialize all to zero
// set request/response code // set request/response code
packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue; packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue;

@ -15,12 +15,10 @@ import tools.BytesArrayTools;
*/ */
public class FilePart extends Payload { public class FilePart extends Payload {
private String filename; private String filename;
private long totalSize;
private long offset; private long offset;
private byte[] partialContent; private byte[] partialContent;
static final private int OFFSET_POSITION = PAYLOAD_START_POSITION; static final private int OFFSET_POSITION = PAYLOAD_START_POSITION;
static final private int TOTAL_FILESIZE_POSITION = OFFSET_POSITION + 8; static final private int FILENAME_SIZE_POSITION = OFFSET_POSITION + 8;
static final private int FILENAME_SIZE_POSITION = TOTAL_FILESIZE_POSITION + 8;
static final private int FILENAME_POSITION = FILENAME_SIZE_POSITION + 4; static final private int FILENAME_POSITION = FILENAME_SIZE_POSITION + 4;
/** Constructor (typically used by server) with informations about file part to send as parameters. /** Constructor (typically used by server) with informations about file part to send as parameters.
@ -30,20 +28,16 @@ public class FilePart extends Payload {
* @param partialContent content of the file we send * @param partialContent content of the file we send
* @throws InternalError * @throws InternalError
*/ */
public FilePart(String filename, long totalSize, long offset, byte[] partialContent) throws InternalError { public FilePart(String filename, long offset, byte[] partialContent) throws InternalError {
super(RequestResponseCode.LOAD_RESPONSE); super(RequestResponseCode.LOAD_RESPONSE);
/* asserts to help debugging */ /* asserts to help debugging */
assert totalSize >= 0 : "totalSize cannot be negative";
assert partialContent.length != 0 : "partialContent.length cannot be zero, see RRCode.EMPTY_FILE"; assert partialContent.length != 0 : "partialContent.length cannot be zero, see RRCode.EMPTY_FILE";
assert totalSize >= partialContent.length : "totalSize must be greater than partialContent.length";
assert offset >= 0 : "offset cannot be negative"; assert offset >= 0 : "offset cannot be negative";
assert filename != null : "filename is required"; assert filename != null : "filename is required";
if (totalSize < 0 || partialContent.length == 0 || totalSize < partialContent.length if (partialContent.length == 0 || offset < 0 || filename == null) {
|| offset < 0 || filename == null) {
throw new InternalError(); throw new InternalError();
} }
this.filename = filename; this.filename = filename;
this.totalSize = totalSize;
this.offset = offset; this.offset = offset;
this.partialContent = partialContent; this.partialContent = partialContent;
} }
@ -63,7 +57,6 @@ public class FilePart extends Payload {
throw new InternalError(); throw new InternalError();
} }
setOffset(packet); // this can throw SizeError setOffset(packet); // this can throw SizeError
setTotalSize(packet); // this can throw SizeError
setFilename(packet); // this can throw ProtocolError, SizeError setFilename(packet); // this can throw ProtocolError, SizeError
setPartialContent(packet); // this can throw SizeError setPartialContent(packet); // this can throw SizeError
} }
@ -84,8 +77,6 @@ public class FilePart extends Payload {
setPayloadSize(size - PAYLOAD_START_POSITION, packet); setPayloadSize(size - PAYLOAD_START_POSITION, packet);
// write offset to Packet // write offset to Packet
BytesArrayTools.write(packet, OFFSET_POSITION, offset); BytesArrayTools.write(packet, OFFSET_POSITION, offset);
// write totalSize to Packet
BytesArrayTools.write(packet, TOTAL_FILESIZE_POSITION, totalSize);
// write filenames size to Packet // write filenames size to Packet
BytesArrayTools.write(packet, FILENAME_SIZE_POSITION, filename.length()); BytesArrayTools.write(packet, FILENAME_SIZE_POSITION, filename.length());
// write filename to Packet // write filename to Packet
@ -102,13 +93,6 @@ public class FilePart extends Payload {
private void setOffset(byte[] packet) throws SizeError { private void setOffset(byte[] packet) throws SizeError {
offset = BytesArrayTools.readLong(packet, OFFSET_POSITION); offset = BytesArrayTools.readLong(packet, OFFSET_POSITION);
} }
/** Write from Packet into totalSize.
* @param packet received Packet
* @throws SizeError
*/
private void setTotalSize(byte[] packet) throws SizeError {
totalSize = BytesArrayTools.readLong(packet, TOTAL_FILESIZE_POSITION);
}
/** Read filenames size from Packet. /** Read filenames size from Packet.
* @param packet received Packet * @param packet received Packet
@ -171,11 +155,4 @@ public class FilePart extends Payload {
public long getOffset() { public long getOffset() {
return offset; return offset;
} }
/** totalSize getter.
* @return totalSize
*/
public long getTotalSize() {
return totalSize;
}
} }

@ -86,7 +86,7 @@ public class LoadRequest extends Payload {
// compute size // compute size
int filenameSize = filename.length(); int filenameSize = filename.length();
String hostname = hostItem.getHostname(); String hostname = hostItem.getHostname();
int size = 1 + FILENAME_POSITION + filenameSize + 2 + hostname.length(); int size = FILENAME_POSITION + filenameSize + 2 + hostname.length();
byte[] packet = new byte[size]; // java initialize all to zero byte[] packet = new byte[size]; // java initialize all to zero
// set request/response code // set request/response code
packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue; packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue;

@ -13,6 +13,8 @@ import protocolP2P.RatioRequest;
import protocolP2P.RatioResponse; import protocolP2P.RatioResponse;
import protocolP2P.UpdateRatio; import protocolP2P.UpdateRatio;
import protocolP2P.Denied; import protocolP2P.Denied;
import protocolP2P.SizeRequest;
import protocolP2P.SizeResponse;
import localException.ProtocolError; import localException.ProtocolError;
import localException.InternalError; import localException.InternalError;
import localException.TransmissionError; import localException.TransmissionError;
@ -48,6 +50,8 @@ public class Payload {
assert requestResponseCode != RequestResponseCode.RATIO_RESPONSE || (this instanceof RatioResponse) : "RATIO_RESPONSE must use RatioResponse class"; assert requestResponseCode != RequestResponseCode.RATIO_RESPONSE || (this instanceof RatioResponse) : "RATIO_RESPONSE must use RatioResponse class";
assert requestResponseCode != RequestResponseCode.UPDATE_RATIO || (this instanceof UpdateRatio) : "UPDATE_RATIO must use UpdateRatio class"; assert requestResponseCode != RequestResponseCode.UPDATE_RATIO || (this instanceof UpdateRatio) : "UPDATE_RATIO must use UpdateRatio class";
assert requestResponseCode != RequestResponseCode.DENIED || (this instanceof Denied) : "DENIED must use Denied class"; assert requestResponseCode != RequestResponseCode.DENIED || (this instanceof Denied) : "DENIED must use Denied class";
assert requestResponseCode != RequestResponseCode.SIZE_REQUEST || (this instanceof SizeRequest) : "SIZE_REQUEST must use SizeRequest class";
assert requestResponseCode != RequestResponseCode.SIZE_RESPONSE || (this instanceof SizeResponse) : "SIZE_RESPONSE must use SizeResponse class";
this.requestResponseCode = requestResponseCode; this.requestResponseCode = requestResponseCode;
checkRequestResponseCode(); // this can throw InternalError checkRequestResponseCode(); // this can throw InternalError
} }
@ -79,6 +83,8 @@ public class Payload {
assert RequestResponseCode.fromCode(packet[RequestResponseCode.RRCODE_POSITION]) != RequestResponseCode.RATIO_RESPONSE || (this instanceof RatioResponse) : "RATIO_RESPONSE must use RatioResponse class"; assert RequestResponseCode.fromCode(packet[RequestResponseCode.RRCODE_POSITION]) != RequestResponseCode.RATIO_RESPONSE || (this instanceof RatioResponse) : "RATIO_RESPONSE must use RatioResponse class";
assert RequestResponseCode.fromCode(packet[RequestResponseCode.RRCODE_POSITION]) != RequestResponseCode.UPDATE_RATIO || (this instanceof UpdateRatio) : "UPDATE_RATIO must use UpdateRatio class"; assert RequestResponseCode.fromCode(packet[RequestResponseCode.RRCODE_POSITION]) != RequestResponseCode.UPDATE_RATIO || (this instanceof UpdateRatio) : "UPDATE_RATIO must use UpdateRatio class";
assert RequestResponseCode.fromCode(packet[RequestResponseCode.RRCODE_POSITION]) != RequestResponseCode.DENIED || (this instanceof Denied) : "DENIED must use Denied class"; assert RequestResponseCode.fromCode(packet[RequestResponseCode.RRCODE_POSITION]) != RequestResponseCode.DENIED || (this instanceof Denied) : "DENIED must use Denied class";
assert RequestResponseCode.fromCode(packet[RequestResponseCode.RRCODE_POSITION]) != RequestResponseCode.SIZE_REQUEST || (this instanceof SizeRequest) : "SIZE_REQUEST must use SizeRequest class";
assert RequestResponseCode.fromCode(packet[RequestResponseCode.RRCODE_POSITION]) != RequestResponseCode.SIZE_RESPONSE || (this instanceof SizeResponse) : "SIZE_RESPONSE must use SizeResponse class";
requestResponseCode = RequestResponseCode.fromCode(packet[RequestResponseCode.RRCODE_POSITION]); requestResponseCode = RequestResponseCode.fromCode(packet[RequestResponseCode.RRCODE_POSITION]);
checkRequestResponseCode(); // this can throw InternalError checkRequestResponseCode(); // this can throw InternalError
} }
@ -101,6 +107,8 @@ public class Payload {
|| (requestResponseCode == RequestResponseCode.RATIO_RESPONSE && !(this instanceof RatioResponse)) || (requestResponseCode == RequestResponseCode.RATIO_RESPONSE && !(this instanceof RatioResponse))
|| (requestResponseCode == RequestResponseCode.UPDATE_RATIO && !(this instanceof UpdateRatio)) || (requestResponseCode == RequestResponseCode.UPDATE_RATIO && !(this instanceof UpdateRatio))
|| (requestResponseCode == RequestResponseCode.DENIED && !(this instanceof Denied)) || (requestResponseCode == RequestResponseCode.DENIED && !(this instanceof Denied))
|| (requestResponseCode == RequestResponseCode.SIZE_REQUEST && !(this instanceof SizeRequest))
|| (requestResponseCode == RequestResponseCode.SIZE_RESPONSE && !(this instanceof SizeResponse))
) { ) {
throw new InternalError(); throw new InternalError();
} }

@ -22,6 +22,8 @@ import protocolP2P.RatioRequest;
import protocolP2P.RatioResponse; import protocolP2P.RatioResponse;
import protocolP2P.UpdateRatio; import protocolP2P.UpdateRatio;
import protocolP2P.Denied; import protocolP2P.Denied;
import protocolP2P.SizeRequest;
import protocolP2P.SizeResponse;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.Socket; import java.net.Socket;
@ -147,6 +149,7 @@ public class ProtocolP2PPacketTCP < T extends Payload > extends ProtocolP2PPacke
case NOT_A_TRACKER: case NOT_A_TRACKER:
case RATIO_RESPONSE: case RATIO_RESPONSE:
case DENIED: case DENIED:
case SIZE_RESPONSE:
// we were expecting a request, but we are receiving a response // we were expecting a request, but we are receiving a response
throw new ProtocolError(); throw new ProtocolError();
default : default :
@ -337,6 +340,12 @@ public class ProtocolP2PPacketTCP < T extends Payload > extends ProtocolP2PPacke
case DENIED: case DENIED:
payload = (Payload) new Denied(packet); payload = (Payload) new Denied(packet);
break; break;
case SIZE_REQUEST:
payload = (Payload) new SizeRequest(packet);
break;
case SIZE_RESPONSE:
payload = (Payload) new SizeResponse(packet);
break;
default: default:
payload = new Payload(packet); // this can throw TransmissionError payload = new Payload(packet); // this can throw TransmissionError
break; break;

@ -23,6 +23,8 @@ import protocolP2P.RatioRequest;
import protocolP2P.RatioResponse; import protocolP2P.RatioResponse;
import protocolP2P.UpdateRatio; import protocolP2P.UpdateRatio;
import protocolP2P.Denied; import protocolP2P.Denied;
import protocolP2P.SizeRequest;
import protocolP2P.SizeResponse;
import java.net.DatagramPacket; import java.net.DatagramPacket;
import java.net.DatagramSocket; import java.net.DatagramSocket;
import java.net.SocketAddress; import java.net.SocketAddress;
@ -140,6 +142,7 @@ public class ProtocolP2PPacketUDP < T extends Payload> extends ProtocolP2PPacket
case NOT_A_TRACKER: case NOT_A_TRACKER:
case RATIO_RESPONSE: case RATIO_RESPONSE:
case DENIED: case DENIED:
case SIZE_RESPONSE:
// we were expecting a request, but we are receiving a response // we were expecting a request, but we are receiving a response
throw new ProtocolError(); throw new ProtocolError();
default : default :
@ -322,6 +325,12 @@ public class ProtocolP2PPacketUDP < T extends Payload> extends ProtocolP2PPacket
case DENIED: case DENIED:
payload = (Payload) new Denied(packet); payload = (Payload) new Denied(packet);
break; break;
case SIZE_REQUEST:
payload = (Payload) new SizeRequest(packet);
break;
case SIZE_RESPONSE:
payload = (Payload) new SizeResponse(packet);
break;
default: default:
payload = new Payload(packet); // this can throw TransmissionError payload = new Payload(packet); // this can throw TransmissionError
break; break;

@ -50,7 +50,7 @@ public class RatioRequest extends Payload {
protected byte[] toPacket() throws InternalError { protected byte[] toPacket() throws InternalError {
String hostname = hostItem.getHostname(); String hostname = hostItem.getHostname();
// compute total size // compute total size
int size = 1 + HOSTNAME_START_POSITION + hostname.length(); int size = HOSTNAME_START_POSITION + hostname.length();
byte[] packet = new byte[size]; // java initialize all to zero byte[] packet = new byte[size]; // java initialize all to zero
// set request/response code // set request/response code
packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue; packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue;

@ -61,7 +61,7 @@ public class RatioResponse extends Payload {
protected byte[] toPacket() throws InternalError { protected byte[] toPacket() throws InternalError {
String hostname = hostItem.getHostname(); String hostname = hostItem.getHostname();
// compute total size // compute total size
int size = 1 + HOSTNAME_START_POSITION + hostname.length(); int size = HOSTNAME_START_POSITION + hostname.length();
byte[] packet = new byte[size]; // java initialize all to zero byte[] packet = new byte[size]; // java initialize all to zero
// set request/response code // set request/response code
packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue; packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue;

@ -50,7 +50,7 @@ public class Register extends Payload {
protected byte[] toPacket() throws InternalError { protected byte[] toPacket() throws InternalError {
String hostname = hostItem.getHostname(); String hostname = hostItem.getHostname();
// compute total size // compute total size
int size = 1 + HOSTNAME_START_POSITION + hostname.length(); int size = HOSTNAME_START_POSITION + hostname.length();
byte[] packet = new byte[size]; // java initialize all to zero byte[] packet = new byte[size]; // java initialize all to zero
// set request/response code // set request/response code
packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue; packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue;

@ -20,12 +20,14 @@ public enum RequestResponseCode {
UNREGISTER(CodeType.REQUEST_TRACKER, (byte)0x05), UNREGISTER(CodeType.REQUEST_TRACKER, (byte)0x05),
RATIO_REQUEST(CodeType.REQUEST_TRACKER, (byte)0x06), RATIO_REQUEST(CodeType.REQUEST_TRACKER, (byte)0x06),
UPDATE_RATIO(CodeType.REQUEST_TRACKER, (byte)0x07), UPDATE_RATIO(CodeType.REQUEST_TRACKER, (byte)0x07),
SIZE_REQUEST(CodeType.REQUEST, (byte)0x08),
LIST_RESPONSE(CodeType.RESPONSE, (byte)0x80), LIST_RESPONSE(CodeType.RESPONSE, (byte)0x80),
LOAD_RESPONSE(CodeType.RESPONSE, (byte)0x81), LOAD_RESPONSE(CodeType.RESPONSE, (byte)0x81),
HASH_RESPONSE(CodeType.RESPONSE, (byte)0x82), HASH_RESPONSE(CodeType.RESPONSE, (byte)0x82),
DISCOVER_RESPONSE(CodeType.RESPONSE, (byte)0x83), DISCOVER_RESPONSE(CodeType.RESPONSE, (byte)0x83),
RATIO_RESPONSE(CodeType.RESPONSE, (byte)0x86), RATIO_RESPONSE(CodeType.RESPONSE, (byte)0x86),
DENIED(CodeType.RESPONSE, (byte)0x87), DENIED(CodeType.RESPONSE, (byte)0x87),
SIZE_RESPONSE(CodeType.RESPONSE, (byte)0x88),
VERSION_ERROR(CodeType.ERROR, (byte)0xC0), VERSION_ERROR(CodeType.ERROR, (byte)0xC0),
PROTOCOL_ERROR(CodeType.ERROR, (byte)0xC1), PROTOCOL_ERROR(CodeType.ERROR, (byte)0xC1),
INTERNAL_ERROR(CodeType.ERROR, (byte)0xC2), INTERNAL_ERROR(CodeType.ERROR, (byte)0xC2),

@ -0,0 +1,70 @@
package protocolP2P;
import protocolP2P.Payload;
import protocolP2P.RequestResponseCode;
import localException.TransmissionError;
import localException.ProtocolError;
import localException.InternalError;
import localException.SizeError;
import tools.BytesArrayTools;
import tools.HostItem;
/** Representation of payload for load request.
* @author Louis Royer
* @author Flavien Haas
* @author JS Auge
* @version 1.0
*/
public class SizeRequest extends Payload {
private String filename;
/** Constructor (typically used by the client) with a filename parameter.
* @param filename name of the file to download. Must not be empty.
*/
public SizeRequest(String filename) throws InternalError {
super(RequestResponseCode.SIZE_REQUEST);
/* assert to help debugging */
assert filename.length() != 0 : "Payload size of LoadRequest must not be empty";
if (filename.length() == 0) {
throw new InternalError();
}
this.filename = filename;
}
/** Constructor (typically used by server) with a byte[] parameter containing the Packet received.
* @param packet the full Packet received
* @throws SizeError
* @throws InternalError
* @throws ProtocolError
* @throws TransmissionError
*/
protected SizeRequest(byte[] packet) throws TransmissionError, SizeError, ProtocolError, InternalError {
super(packet);
/* Read filename */
int size = getPayloadSize(packet);
filename = BytesArrayTools.readString(packet, PAYLOAD_START_POSITION, size);
}
/** 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 {
int size = PAYLOAD_START_POSITION + filename.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 filename
BytesArrayTools.write(packet, filename, PAYLOAD_START_POSITION);
return packet;
}
/** filename getter.
* @return filename
*/
public String getFilename() {
return filename;
}
}

@ -0,0 +1,86 @@
package protocolP2P;
import protocolP2P.Payload;
import protocolP2P.RequestResponseCode;
import localException.ProtocolError;
import localException.InternalError;
import localException.SizeError;
import localException.TransmissionError;
import tools.BytesArrayTools;
/** Representation of payload for size response.
* @author Louis Royer
* @author Flavien Haas
* @author JS Auge
* @version 1.0
*/
public class SizeResponse extends Payload {
private String filename;
private long totalSize;
static final private int TOTAL_SIZE_POSITION = PAYLOAD_START_POSITION;
static final private int FILENAME_POSITION = TOTAL_SIZE_POSITION + 8;
/** Constructor (typically used by server) with informations about file part to send as parameters.
* @param filename name of the file
* @param totalSize size of the file
* @throws InternalError
*/
public SizeResponse(String filename, long totalSize) throws InternalError {
super(RequestResponseCode.SIZE_RESPONSE);
/* asserts to help debugging */
assert totalSize >= 0 : "offset cannot be negative";
assert filename != null : "filename is required";
if (filename == null || totalSize < 0) {
throw new InternalError();
}
this.filename = filename;
this.totalSize = totalSize;
}
/** Constructor (typically used by client) with Packet received as parameter.
* @param packet the full Packet received
* @throws SizeError
* @throws InternalError
* @throws TransmissionError
*/
protected SizeResponse(byte[] packet) throws TransmissionError, SizeError, ProtocolError, InternalError {
super(packet);
int filenameSize = getPayloadSize(packet) - FILENAME_POSITION + PAYLOAD_START_POSITION;
totalSize = BytesArrayTools.readLong(packet, TOTAL_SIZE_POSITION);
filename = BytesArrayTools.readString(packet, FILENAME_POSITION, filenameSize);
}
/** 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 {
// compute total size
int size = FILENAME_POSITION + filename.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 totalSize to Packet
BytesArrayTools.write(packet, TOTAL_SIZE_POSITION, totalSize);
// write filename to Packet
BytesArrayTools.write(packet, filename, FILENAME_POSITION);
return packet;
}
/** filename getter.
* @return String
*/
public String getFilename() {
return filename;
}
/** totalSize getter.
* @return totalSize
*/
public long getTotalSize() {
return totalSize;
}
}

@ -50,7 +50,7 @@ public class Unregister extends Payload {
protected byte[] toPacket() throws InternalError { protected byte[] toPacket() throws InternalError {
String hostname = hostItem.getHostname(); String hostname = hostItem.getHostname();
// compute total size // compute total size
int size = 1 + HOSTNAME_START_POSITION + hostname.length(); int size = HOSTNAME_START_POSITION + hostname.length();
byte[] packet = new byte[size]; // java initialize all to zero byte[] packet = new byte[size]; // java initialize all to zero
// set request/response code // set request/response code
packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue; packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue;

@ -62,7 +62,7 @@ public class UpdateRatio extends Payload {
protected byte[] toPacket() throws InternalError { protected byte[] toPacket() throws InternalError {
String[] hostnames = { server.getHostname(), client.getHostname()}; String[] hostnames = { server.getHostname(), client.getHostname()};
// compute total size // compute total size
int size = 1 + HOSTNAMES_START_POSITION + BytesArrayTools.computeStringArraySize(hostnames, "\n"); int size = HOSTNAMES_START_POSITION + BytesArrayTools.computeStringArraySize(hostnames, "\n");
byte[] packet = new byte[size]; // java initialize all to zero byte[] packet = new byte[size]; // java initialize all to zero
// set request/response code // set request/response code
packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue; packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue;

@ -14,8 +14,11 @@ import protocolP2P.HashRequest;
import protocolP2P.HashResponse; import protocolP2P.HashResponse;
import protocolP2P.HashAlgorithm; import protocolP2P.HashAlgorithm;
import protocolP2P.Unregister; import protocolP2P.Unregister;
import protocolP2P.SizeRequest;
import protocolP2P.SizeResponse;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.nio.file.Files; import java.nio.file.Files;
import java.io.File;
import java.util.Arrays; import java.util.Arrays;
import java.util.Map; import java.util.Map;
import java.util.HashMap; import java.util.HashMap;
@ -153,7 +156,7 @@ public abstract class ServerManagement extends ServeErrors implements Runnable {
if (load.length == 0) { if (load.length == 0) {
sendEmptyFile(pd); sendEmptyFile(pd);
} else { } else {
pd.sendResponse(createProtocolP2PPacket((Payload)(new FilePart(filename, fullLoad.length, offset, load)))); pd.sendResponse(createProtocolP2PPacket((Payload)(new FilePart(filename, offset, load))));
} }
} catch (Exception e2) { } catch (Exception e2) {
writeLog(e2, LogLevel.Error); writeLog(e2, LogLevel.Error);
@ -177,6 +180,42 @@ public abstract class ServerManagement extends ServeErrors implements Runnable {
} }
} }
/** Send response to size request
* @param pd Request received
*/
protected < T extends ProtocolP2PPacket<?> > void sendSizeResponse(T pd) {
Payload p = pd.getPayload();
assert p instanceof SizeRequest : "payload must be an instance of SizeRequest";
if (!(p instanceof SizeRequest)) {
sendInternalError(pd);
} else {
String filename = ((SizeRequest)p).getFilename();
try {
long size = (new File(baseDirectory + filename)).length();
String[] fileList = fileListWatcher.getFileList();
if (Arrays.binarySearch(fileList, filename) >= 0) {
try {
if (size == 0) {
sendEmptyFile(pd);
} else {
pd.sendResponse(createProtocolP2PPacket((new SizeResponse(filename, size))));
}
} catch (Exception e2) {
writeLog(e2, LogLevel.Error);
}
} else {
throw new IOException(); // to send a NOT_FOUND in the catch block
}
} catch (IOException e) {
try {
sendNotFound(pd);
} catch (Exception e2) {
writeLog(e2, LogLevel.Debug);
}
}
}
}
/** Getter for tracker socket /** Getter for tracker socket
*/ */
@ -205,6 +244,10 @@ public abstract class ServerManagement extends ServeErrors implements Runnable {
writeLog("Received LOAD_REQUEST from host " + pd.getHostItem(), LogLevel.Action); writeLog("Received LOAD_REQUEST from host " + pd.getHostItem(), LogLevel.Action);
sendLoadResponse(pd); sendLoadResponse(pd);
break; break;
case SIZE_REQUEST:
writeLog("Received SIZE_REQUEST from host " + pd.getHostItem(), LogLevel.Action);
sendSizeResponse(pd);
break;
case LIST_REQUEST: case LIST_REQUEST:
writeLog("Received LIST_REQUEST from host " + pd.getHostItem(), LogLevel.Action); writeLog("Received LIST_REQUEST from host " + pd.getHostItem(), LogLevel.Action);
sendListResponse(pd); sendListResponse(pd);

Loading…
Cancel
Save