Fix #41
All checks were successful
flavien's git/Projet_JAVA_P2P_STRI2A/pipeline/pr-etape5 This commit looks good
All checks were successful
flavien's git/Projet_JAVA_P2P_STRI2A/pipeline/pr-etape5 This commit looks good
This commit is contained in:
parent
77655cb828
commit
c81f5d2e5a
@ -22,6 +22,7 @@ x bytes: [(bytes 8-?): PAYLOAD]
|
||||
- `UNREGISTER` (0x05)
|
||||
- `RATIO` (0x06)
|
||||
- `UPDATE RATIO` (0x07)
|
||||
- `SIZE` (0x08)
|
||||
|
||||
- RESPONSES (msb is 1):
|
||||
- `LIST` (0x80)
|
||||
@ -30,6 +31,7 @@ x bytes: [(bytes 8-?): PAYLOAD]
|
||||
- `DISCOVER` (0x83)
|
||||
- `RATIO` (0x86)
|
||||
- `DENIED` (0x87)
|
||||
- `SIZE` (0x88)
|
||||
- `VERSION ERROR` (0xC0)
|
||||
- `PROTOCOL ERROR` (0xC1)
|
||||
- `INTERNAL ERROR` (0xC2)
|
||||
@ -59,7 +61,6 @@ Payload contains
|
||||
|
||||
```text
|
||||
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)
|
||||
y bytes: [<FILENAME>]
|
||||
z bytes: [PARTIAL CONTENT]
|
||||
@ -78,6 +79,23 @@ y bytes: [<FILENAME>]
|
||||
```
|
||||
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 request
|
||||
Get hash of a file. Payload contains
|
||||
|
@ -29,7 +29,8 @@ import protocolP2P.HashResponse;
|
||||
import protocolP2P.HashRequest;
|
||||
import protocolP2P.Payload;
|
||||
import protocolP2P.FilePart;
|
||||
import protocolP2P.LoadRequest;
|
||||
import protocolP2P.SizeRequest;
|
||||
import protocolP2P.SizeResponse;
|
||||
import protocolP2P.ProtocolP2PPacket;
|
||||
import clientP2P.ClientDownloadPart;
|
||||
import tools.HostItem;
|
||||
@ -291,39 +292,22 @@ public abstract class ClientDownload extends ServeErrors implements Runnable {
|
||||
* @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 {
|
||||
d.sendRequest(getHostItemSocket(hostList.get(0)));
|
||||
try {
|
||||
Payload p = d.receiveResponse().getPayload();
|
||||
assert p instanceof FilePart : "This payload must be instance of FilePart";
|
||||
if (!(p instanceof FilePart)) {
|
||||
System.err.println("Error: cannot get size.");
|
||||
assert p instanceof SizeResponse : "This payload must be instance of SizeResponse";
|
||||
if (!(p instanceof SizeResponse)) {
|
||||
writeLog("cannot get size.", LogLevel.Error);
|
||||
throw new InternalError();
|
||||
} else {
|
||||
FilePart fp = (FilePart)p;
|
||||
SizeResponse fp = (SizeResponse)p;
|
||||
if (!fp.getFilename().equals(filename)) {
|
||||
System.err.println("Error: wrong file received: `" + fp.getFilename() + "`");
|
||||
writeLog("wrong file received: `" + fp.getFilename() + "`", LogLevel.Error);
|
||||
writeLog("wrong file size received: `" + fp.getFilename() + "`", LogLevel.Error);
|
||||
throw new ProtocolError();
|
||||
}
|
||||
if (fp.getOffset() == 0) {
|
||||
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();
|
||||
}
|
||||
size = fp.getTotalSize();
|
||||
}
|
||||
} catch (EmptyDirectory e) {
|
||||
System.err.println("Error: empty directory.");
|
||||
@ -395,7 +379,7 @@ public abstract class ClientDownload extends ServeErrors implements Runnable {
|
||||
|
||||
// Add tasks
|
||||
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));
|
||||
}
|
||||
writeLog("Adding tasks: done", LogLevel.Info);
|
||||
|
@ -50,7 +50,7 @@ public class DiscoverRequest extends Payload {
|
||||
*/
|
||||
protected byte[] toPacket() throws InternalError {
|
||||
// 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
|
||||
// set request/response code
|
||||
packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue;
|
||||
|
@ -74,7 +74,7 @@ public class DiscoverResponse extends Payload {
|
||||
hostListSize += (2 + hostItem.getHostname().length() + 1);
|
||||
}
|
||||
// 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
|
||||
// set request/response code
|
||||
packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue;
|
||||
|
@ -15,12 +15,10 @@ import tools.BytesArrayTools;
|
||||
*/
|
||||
public class FilePart extends Payload {
|
||||
private String filename;
|
||||
private long totalSize;
|
||||
private long offset;
|
||||
private byte[] partialContent;
|
||||
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 = TOTAL_FILESIZE_POSITION + 8;
|
||||
static final private int FILENAME_SIZE_POSITION = OFFSET_POSITION + 8;
|
||||
static final private int FILENAME_POSITION = FILENAME_SIZE_POSITION + 4;
|
||||
|
||||
/** 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
|
||||
* @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);
|
||||
/* 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 totalSize >= partialContent.length : "totalSize must be greater than partialContent.length";
|
||||
assert offset >= 0 : "offset cannot be negative";
|
||||
assert filename != null : "filename is required";
|
||||
if (totalSize < 0 || partialContent.length == 0 || totalSize < partialContent.length
|
||||
|| offset < 0 || filename == null) {
|
||||
if (partialContent.length == 0 || offset < 0 || filename == null) {
|
||||
throw new InternalError();
|
||||
}
|
||||
this.filename = filename;
|
||||
this.totalSize = totalSize;
|
||||
this.offset = offset;
|
||||
this.partialContent = partialContent;
|
||||
}
|
||||
@ -63,7 +57,6 @@ public class FilePart extends Payload {
|
||||
throw new InternalError();
|
||||
}
|
||||
setOffset(packet); // this can throw SizeError
|
||||
setTotalSize(packet); // this can throw SizeError
|
||||
setFilename(packet); // this can throw ProtocolError, SizeError
|
||||
setPartialContent(packet); // this can throw SizeError
|
||||
}
|
||||
@ -84,8 +77,6 @@ public class FilePart extends Payload {
|
||||
setPayloadSize(size - PAYLOAD_START_POSITION, packet);
|
||||
// write offset to Packet
|
||||
BytesArrayTools.write(packet, OFFSET_POSITION, offset);
|
||||
// write totalSize to Packet
|
||||
BytesArrayTools.write(packet, TOTAL_FILESIZE_POSITION, totalSize);
|
||||
// write filename’s size to Packet
|
||||
BytesArrayTools.write(packet, FILENAME_SIZE_POSITION, filename.length());
|
||||
// write filename to Packet
|
||||
@ -102,13 +93,6 @@ public class FilePart extends Payload {
|
||||
private void setOffset(byte[] packet) throws SizeError {
|
||||
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 filename’s size from Packet.
|
||||
* @param packet received Packet
|
||||
@ -171,11 +155,4 @@ public class FilePart extends Payload {
|
||||
public long getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
/** totalSize getter.
|
||||
* @return totalSize
|
||||
*/
|
||||
public long getTotalSize() {
|
||||
return totalSize;
|
||||
}
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ public class LoadRequest extends Payload {
|
||||
// compute size
|
||||
int filenameSize = filename.length();
|
||||
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
|
||||
// set request/response code
|
||||
packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue;
|
||||
|
@ -13,6 +13,8 @@ import protocolP2P.RatioRequest;
|
||||
import protocolP2P.RatioResponse;
|
||||
import protocolP2P.UpdateRatio;
|
||||
import protocolP2P.Denied;
|
||||
import protocolP2P.SizeRequest;
|
||||
import protocolP2P.SizeResponse;
|
||||
import localException.ProtocolError;
|
||||
import localException.InternalError;
|
||||
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.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.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;
|
||||
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.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.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]);
|
||||
checkRequestResponseCode(); // this can throw InternalError
|
||||
}
|
||||
@ -101,6 +107,8 @@ public class Payload {
|
||||
|| (requestResponseCode == RequestResponseCode.RATIO_RESPONSE && !(this instanceof RatioResponse))
|
||||
|| (requestResponseCode == RequestResponseCode.UPDATE_RATIO && !(this instanceof UpdateRatio))
|
||||
|| (requestResponseCode == RequestResponseCode.DENIED && !(this instanceof Denied))
|
||||
|| (requestResponseCode == RequestResponseCode.SIZE_REQUEST && !(this instanceof SizeRequest))
|
||||
|| (requestResponseCode == RequestResponseCode.SIZE_RESPONSE && !(this instanceof SizeResponse))
|
||||
) {
|
||||
throw new InternalError();
|
||||
}
|
||||
|
@ -22,6 +22,8 @@ import protocolP2P.RatioRequest;
|
||||
import protocolP2P.RatioResponse;
|
||||
import protocolP2P.UpdateRatio;
|
||||
import protocolP2P.Denied;
|
||||
import protocolP2P.SizeRequest;
|
||||
import protocolP2P.SizeResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.Socket;
|
||||
@ -147,6 +149,7 @@ public class ProtocolP2PPacketTCP < T extends Payload > extends ProtocolP2PPacke
|
||||
case NOT_A_TRACKER:
|
||||
case RATIO_RESPONSE:
|
||||
case DENIED:
|
||||
case SIZE_RESPONSE:
|
||||
// we were expecting a request, but we are receiving a response
|
||||
throw new ProtocolError();
|
||||
default :
|
||||
@ -337,6 +340,12 @@ public class ProtocolP2PPacketTCP < T extends Payload > extends ProtocolP2PPacke
|
||||
case DENIED:
|
||||
payload = (Payload) new Denied(packet);
|
||||
break;
|
||||
case SIZE_REQUEST:
|
||||
payload = (Payload) new SizeRequest(packet);
|
||||
break;
|
||||
case SIZE_RESPONSE:
|
||||
payload = (Payload) new SizeResponse(packet);
|
||||
break;
|
||||
default:
|
||||
payload = new Payload(packet); // this can throw TransmissionError
|
||||
break;
|
||||
|
@ -23,6 +23,8 @@ import protocolP2P.RatioRequest;
|
||||
import protocolP2P.RatioResponse;
|
||||
import protocolP2P.UpdateRatio;
|
||||
import protocolP2P.Denied;
|
||||
import protocolP2P.SizeRequest;
|
||||
import protocolP2P.SizeResponse;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.SocketAddress;
|
||||
@ -140,6 +142,7 @@ public class ProtocolP2PPacketUDP < T extends Payload> extends ProtocolP2PPacket
|
||||
case NOT_A_TRACKER:
|
||||
case RATIO_RESPONSE:
|
||||
case DENIED:
|
||||
case SIZE_RESPONSE:
|
||||
// we were expecting a request, but we are receiving a response
|
||||
throw new ProtocolError();
|
||||
default :
|
||||
@ -322,6 +325,12 @@ public class ProtocolP2PPacketUDP < T extends Payload> extends ProtocolP2PPacket
|
||||
case DENIED:
|
||||
payload = (Payload) new Denied(packet);
|
||||
break;
|
||||
case SIZE_REQUEST:
|
||||
payload = (Payload) new SizeRequest(packet);
|
||||
break;
|
||||
case SIZE_RESPONSE:
|
||||
payload = (Payload) new SizeResponse(packet);
|
||||
break;
|
||||
default:
|
||||
payload = new Payload(packet); // this can throw TransmissionError
|
||||
break;
|
||||
|
@ -50,7 +50,7 @@ public class RatioRequest extends Payload {
|
||||
protected byte[] toPacket() throws InternalError {
|
||||
String hostname = hostItem.getHostname();
|
||||
// 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
|
||||
// set request/response code
|
||||
packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue;
|
||||
|
@ -61,7 +61,7 @@ public class RatioResponse extends Payload {
|
||||
protected byte[] toPacket() throws InternalError {
|
||||
String hostname = hostItem.getHostname();
|
||||
// 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
|
||||
// set request/response code
|
||||
packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue;
|
||||
|
@ -50,7 +50,7 @@ public class Register extends Payload {
|
||||
protected byte[] toPacket() throws InternalError {
|
||||
String hostname = hostItem.getHostname();
|
||||
// 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
|
||||
// set request/response code
|
||||
packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue;
|
||||
|
@ -20,12 +20,14 @@ public enum RequestResponseCode {
|
||||
UNREGISTER(CodeType.REQUEST_TRACKER, (byte)0x05),
|
||||
RATIO_REQUEST(CodeType.REQUEST_TRACKER, (byte)0x06),
|
||||
UPDATE_RATIO(CodeType.REQUEST_TRACKER, (byte)0x07),
|
||||
SIZE_REQUEST(CodeType.REQUEST, (byte)0x08),
|
||||
LIST_RESPONSE(CodeType.RESPONSE, (byte)0x80),
|
||||
LOAD_RESPONSE(CodeType.RESPONSE, (byte)0x81),
|
||||
HASH_RESPONSE(CodeType.RESPONSE, (byte)0x82),
|
||||
DISCOVER_RESPONSE(CodeType.RESPONSE, (byte)0x83),
|
||||
RATIO_RESPONSE(CodeType.RESPONSE, (byte)0x86),
|
||||
DENIED(CodeType.RESPONSE, (byte)0x87),
|
||||
SIZE_RESPONSE(CodeType.RESPONSE, (byte)0x88),
|
||||
VERSION_ERROR(CodeType.ERROR, (byte)0xC0),
|
||||
PROTOCOL_ERROR(CodeType.ERROR, (byte)0xC1),
|
||||
INTERNAL_ERROR(CodeType.ERROR, (byte)0xC2),
|
||||
|
70
src/protocolP2P/SizeRequest.java
Normal file
70
src/protocolP2P/SizeRequest.java
Normal file
@ -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;
|
||||
}
|
||||
}
|
86
src/protocolP2P/SizeResponse.java
Normal file
86
src/protocolP2P/SizeResponse.java
Normal file
@ -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 {
|
||||
String hostname = hostItem.getHostname();
|
||||
// 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
|
||||
// set request/response code
|
||||
packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue;
|
||||
|
@ -62,7 +62,7 @@ public class UpdateRatio extends Payload {
|
||||
protected byte[] toPacket() throws InternalError {
|
||||
String[] hostnames = { server.getHostname(), client.getHostname()};
|
||||
// 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
|
||||
// set request/response code
|
||||
packet[RequestResponseCode.RRCODE_POSITION] = requestResponseCode.codeValue;
|
||||
|
@ -14,8 +14,11 @@ import protocolP2P.HashRequest;
|
||||
import protocolP2P.HashResponse;
|
||||
import protocolP2P.HashAlgorithm;
|
||||
import protocolP2P.Unregister;
|
||||
import protocolP2P.SizeRequest;
|
||||
import protocolP2P.SizeResponse;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.Files;
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
@ -153,7 +156,7 @@ public abstract class ServerManagement extends ServeErrors implements Runnable {
|
||||
if (load.length == 0) {
|
||||
sendEmptyFile(pd);
|
||||
} else {
|
||||
pd.sendResponse(createProtocolP2PPacket((Payload)(new FilePart(filename, fullLoad.length, offset, load))));
|
||||
pd.sendResponse(createProtocolP2PPacket((Payload)(new FilePart(filename, offset, load))));
|
||||
}
|
||||
} catch (Exception e2) {
|
||||
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
|
||||
*/
|
||||
@ -205,6 +244,10 @@ public abstract class ServerManagement extends ServeErrors implements Runnable {
|
||||
writeLog("Received LOAD_REQUEST from host " + pd.getHostItem(), LogLevel.Action);
|
||||
sendLoadResponse(pd);
|
||||
break;
|
||||
case SIZE_REQUEST:
|
||||
writeLog("Received SIZE_REQUEST from host " + pd.getHostItem(), LogLevel.Action);
|
||||
sendSizeResponse(pd);
|
||||
break;
|
||||
case LIST_REQUEST:
|
||||
writeLog("Received LIST_REQUEST from host " + pd.getHostItem(), LogLevel.Action);
|
||||
sendListResponse(pd);
|
||||
|
Loading…
Reference in New Issue
Block a user