mirror of
https://github.com/binlaab/nanofiles.git
synced 2026-07-01 12:37:20 +02:00
212 lines
5.0 KiB
Java
212 lines
5.0 KiB
Java
package es.um.redes.nanoFiles.tcp.message;
|
|
|
|
import java.io.DataInputStream;
|
|
import java.io.DataOutputStream;
|
|
import java.io.IOException;
|
|
|
|
import es.um.redes.nanoFiles.util.FileInfo;
|
|
|
|
public class PeerMessage {
|
|
|
|
|
|
|
|
public static final byte HASH_LENGTH = 40;
|
|
private byte opcode;
|
|
|
|
/*
|
|
* TODO: (Boletín MensajesBinarios) Añadir atributos u otros constructores
|
|
* específicos para crear mensajes con otros campos, según sea necesario
|
|
*
|
|
*/
|
|
private boolean last;
|
|
private long fileSize;
|
|
private String fileHash;
|
|
private byte filenameLong;
|
|
private String filenameVal;
|
|
|
|
private byte[] fileData;
|
|
|
|
|
|
|
|
|
|
public PeerMessage() {
|
|
opcode = PeerMessageOps.OPCODE_INVALID_CODE;
|
|
}
|
|
|
|
public PeerMessage(byte op) {
|
|
opcode = op;
|
|
}
|
|
|
|
/*
|
|
* TODO: (Boletín MensajesBinarios) Crear métodos getter y setter para obtener
|
|
* los valores de los atributos de un mensaje. Se aconseja incluir código que
|
|
* compruebe que no se modifica/obtiene el valor de un campo (atributo) que no
|
|
* esté definido para el tipo de mensaje dado por "operation".
|
|
*/
|
|
public byte getOpcode() {
|
|
return opcode;
|
|
}
|
|
|
|
public boolean isLast() {
|
|
return last;
|
|
}
|
|
|
|
public void setLast(boolean last) {
|
|
this.last = last;
|
|
}
|
|
|
|
public boolean getLast() {
|
|
return last;
|
|
}
|
|
|
|
public long getFileSize() {
|
|
return fileSize;
|
|
}
|
|
|
|
public void setFileSize(long fileSize) {
|
|
this.fileSize = fileSize;
|
|
}
|
|
|
|
public String getFileHash() {
|
|
return fileHash;
|
|
}
|
|
|
|
public void setFileHash(String fileHash) {
|
|
this.fileHash = fileHash;
|
|
}
|
|
|
|
public byte getFilenameLong() {
|
|
return filenameLong;
|
|
}
|
|
|
|
public void setFilenameLong(byte filenameLong) {
|
|
this.filenameLong = filenameLong;
|
|
}
|
|
|
|
public String getFilenameVal() {
|
|
return filenameVal;
|
|
}
|
|
|
|
public void setFilenameVal(String filenameVal) {
|
|
this.filenameVal = filenameVal;
|
|
}
|
|
|
|
public byte[] getFileData() {
|
|
return fileData;
|
|
}
|
|
|
|
public void setFileData(byte[] fileData) {
|
|
this.fileData = fileData;
|
|
}
|
|
|
|
/**
|
|
* Método de clase para parsear los campos de un mensaje y construir el objeto
|
|
* DirMessage que contiene los datos del mensaje recibido
|
|
*
|
|
* @param data El array de bytes recibido
|
|
* @return Un objeto de esta clase cuyos atributos contienen los datos del
|
|
* mensaje recibido.
|
|
* @throws IOException
|
|
*/
|
|
public static PeerMessage readMessageFromInputStream(DataInputStream dis) throws IOException {
|
|
/*
|
|
* TODO: (Boletín MensajesBinarios) En función del tipo de mensaje, leer del
|
|
* socket a través del "dis" el resto de campos para ir extrayendo con los
|
|
* valores y establecer los atributos del un objeto DirMessage que contendrá
|
|
* toda la información del mensaje, y que será devuelto como resultado. NOTA:
|
|
* Usar dis.readFully para leer un array de bytes, dis.readInt para leer un
|
|
* entero, etc.
|
|
*/
|
|
byte opcode = dis.readByte();
|
|
PeerMessage message = new PeerMessage(opcode);
|
|
switch (opcode) {
|
|
case PeerMessageOps.OPCODE_REQUEST_PEER_FILES:
|
|
case PeerMessageOps.OPCODE_PEER_FILES_ERROR: break;
|
|
case PeerMessageOps.OPCODE_PEER_FILE: {
|
|
|
|
boolean last = false;
|
|
byte lastVal = dis.readByte();
|
|
|
|
if (lastVal == 1) {
|
|
last = true;
|
|
}
|
|
long fileSize = dis.readLong();
|
|
|
|
byte[] fileHash = new byte[HASH_LENGTH];
|
|
dis.readFully(fileHash);
|
|
|
|
byte filenameLong = dis.readByte();
|
|
byte[] filenameVal = new byte[filenameLong];
|
|
|
|
dis.readFully(filenameVal);
|
|
|
|
message.setLast(last);
|
|
message.setFileSize(fileSize);
|
|
message.setFileHash(new String(fileHash));
|
|
message.setFilenameLong(filenameLong);
|
|
message.setFilenameVal(new String(filenameVal));
|
|
break;
|
|
}
|
|
|
|
case PeerMessageOps.OPCODE_REQUEST_PEER_DL: {
|
|
int longitudSubHash = (int)dis.readByte();
|
|
byte[] subHash = new byte[longitudSubHash];
|
|
dis.readFully(subHash);
|
|
break;
|
|
// buscar archivo supongo
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
default:
|
|
System.err.println("PeerMessage.readMessageFromInputStream doesn't know how to parse this message opcode: "
|
|
+ PeerMessageOps.opcodeToOperation(opcode));
|
|
System.exit(-1);
|
|
}
|
|
return message;
|
|
}
|
|
|
|
public void writeMessageToOutputStream(DataOutputStream dos) throws IOException {
|
|
/*
|
|
* TODO (Boletín MensajesBinarios): Escribir los bytes en los que se codifica el
|
|
* mensaje en el socket a través del "dos", teniendo en cuenta opcode del
|
|
* mensaje del que se trata y los campos relevantes en cada caso. NOTA: Usar
|
|
* dos.write para leer un array de bytes, dos.writeInt para escribir un entero,
|
|
* etc.
|
|
*/
|
|
|
|
dos.writeByte(opcode);
|
|
System.out.println(opcode);
|
|
switch (opcode) {
|
|
case PeerMessageOps.OPCODE_REQUEST_PEER_FILES:
|
|
case PeerMessageOps.OPCODE_PEER_FILES_ERROR: break;
|
|
case PeerMessageOps.OPCODE_PEER_FILE: {
|
|
byte lastVal = 0;
|
|
if (last) {
|
|
lastVal = 1;
|
|
}
|
|
|
|
dos.writeByte(lastVal);
|
|
dos.writeLong(fileSize);
|
|
dos.write(fileHash.getBytes());
|
|
dos.write(filenameLong);
|
|
dos.write(filenameVal.getBytes());
|
|
break;
|
|
}
|
|
|
|
|
|
|
|
|
|
default:
|
|
System.err.println("PeerMessage.writeMessageToOutputStream found unexpected message opcode " + opcode + "("
|
|
+ PeerMessageOps.opcodeToOperation(opcode) + ")");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|