mirror of
https://github.com/binlaab/nanofiles.git
synced 2026-07-01 18:16:29 +02:00
quemen redes
This commit is contained in:
39
TODO.txt
Normal file
39
TODO.txt
Normal file
@@ -0,0 +1,39 @@
|
||||
práctica 2
|
||||
1. hecho
|
||||
2. hecho
|
||||
3. hecho
|
||||
4. hecho
|
||||
|
||||
práctica 3
|
||||
1. hecho
|
||||
2. hecho
|
||||
3. hecho
|
||||
4. hecho
|
||||
|
||||
práctica 4
|
||||
1. hecho
|
||||
2. hecho
|
||||
|
||||
1. hecho?
|
||||
2. hecho
|
||||
3. hecho
|
||||
4. hecho
|
||||
5. hecho
|
||||
6. hecho
|
||||
7. hecho a medias, faltan todos los comandos
|
||||
8. no
|
||||
|
||||
mirar TODOs en DirMessage, DirMessageOps y NFDirectoryServer
|
||||
|
||||
práctica 5 - hecho, revisarlo
|
||||
mirar TODOs en NFController
|
||||
|
||||
práctica 6
|
||||
1 - 3. hechos
|
||||
4- fin. no
|
||||
|
||||
práctica 7
|
||||
especialmente el 9, los demás son pruebas
|
||||
|
||||
práctica 8
|
||||
parcialmente implementados todos los ejercicios
|
||||
@@ -24,7 +24,7 @@ public class NanoFiles {
|
||||
* Flag para pruebas iniciales con TCP, desactivado una vez que la comunicación
|
||||
* cliente-servidor de ficheros está implementada y probada.
|
||||
*/
|
||||
public static boolean testModeTCP = true;
|
||||
public static boolean testModeTCP = false;
|
||||
public static String peerNickname;
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
@@ -12,8 +12,15 @@ public class NFController {
|
||||
* Diferentes estados del cliente de acuerdo con el autómata
|
||||
*/
|
||||
private static final byte OFFLINE = 0;
|
||||
private static final byte WAIT_ACK_PING = 1;
|
||||
private static final byte ONLINE = 2;
|
||||
private static final byte RETRY_PING = 3;
|
||||
private static final byte END = 4;
|
||||
private static final byte WAIT_ACK_REQUESTDIRFILES = 5;
|
||||
private static final byte RETRY_REQUESTDIRFILES = 6;
|
||||
|
||||
/*
|
||||
* TODO: (Boletín Autómatas) Añadir más constantes que representen los estados
|
||||
* DONE: (Boletín Autómatas) Añadir más constantes que representen los estados
|
||||
* del autómata del cliente de directorio.
|
||||
*/
|
||||
|
||||
@@ -138,8 +145,12 @@ public class NFController {
|
||||
commandSucceeded = controllerPeer.listPeerFiles(peerAddr);
|
||||
break;
|
||||
case NFCommands.COM_DOWNLOAD_PEER:
|
||||
if (NanoFiles.testModeTCP) {
|
||||
controllerPeer.testTCPClient();
|
||||
} else {
|
||||
commandSucceeded = controllerPeer.downloadFromPeers(controllerDir, targetPeerNickname,
|
||||
targetHashSubstring);
|
||||
}
|
||||
break;
|
||||
case NFCommands.COM_SERVE:
|
||||
/*
|
||||
@@ -217,6 +228,12 @@ public class NFController {
|
||||
commandAllowed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case NFCommands.COM_PING: {
|
||||
|
||||
// ?????
|
||||
}
|
||||
|
||||
default:
|
||||
// System.err.println("ERROR: undefined behaviour for " + currentCommand + "
|
||||
// command!");
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package es.um.redes.nanoFiles.logic;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.io.IOException;
|
||||
import es.um.redes.nanoFiles.tcp.client.NFConnector;
|
||||
import es.um.redes.nanoFiles.application.NanoFiles;
|
||||
@@ -46,7 +47,21 @@ public class NFControllerLogicP2P {
|
||||
*
|
||||
*/
|
||||
|
||||
try {
|
||||
fileServer = new NFServer();
|
||||
ServerSocket serverSocket = fileServer.getServerSocket();
|
||||
if (serverSocket.isBound()) {
|
||||
System.out.println("Server socket listening on port " + serverSocket.getLocalPort());
|
||||
serverRunning = true;
|
||||
}
|
||||
|
||||
Thread mainServerThread = new Thread(fileServer);
|
||||
mainServerThread.start();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
System.err.println("Cannot start the file server");
|
||||
fileServer = null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -86,7 +101,7 @@ public class NFControllerLogicP2P {
|
||||
assert (NanoFiles.testModeTCP);
|
||||
/*
|
||||
* (Boletín SocketsTCP) Inicialmente, se creará un NFConnector (cliente TCP)
|
||||
* para conectarse a un servidor que esté escuchando en la misma máquina y un
|
||||
* para conectarse a un servidor que esté escuchando en la m isma máquina y un
|
||||
* puerto fijo. Después, se ejecutará el método "test" para comprobar la
|
||||
* comunicación mediante el socket TCP. Posteriormente, se desactivará
|
||||
* "testModeTCP" para implementar la descarga de un fichero desde múltiples
|
||||
@@ -95,6 +110,7 @@ public class NFControllerLogicP2P {
|
||||
|
||||
try {
|
||||
NFConnector nfConnector = new NFConnector(new InetSocketAddress(NFServer.PORT));
|
||||
// meter la ip como primer argumento a InetSocketAddress()
|
||||
nfConnector.test();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
|
||||
@@ -7,6 +7,8 @@ import java.io.RandomAccessFile;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.UnknownHostException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import es.um.redes.nanoFiles.tcp.message.PeerMessage;
|
||||
import es.um.redes.nanoFiles.tcp.message.PeerMessageOps;
|
||||
@@ -18,30 +20,59 @@ public class NFConnector {
|
||||
private InetSocketAddress serverAddr;
|
||||
|
||||
|
||||
|
||||
private DataInputStream dis;
|
||||
private DataOutputStream dos;
|
||||
|
||||
public NFConnector(InetSocketAddress fserverAddr) throws UnknownHostException, IOException {
|
||||
serverAddr = fserverAddr;
|
||||
/*
|
||||
* TODO: (Boletín SocketsTCP) Se crea el socket a partir de la dirección del
|
||||
* done: (Boletín SocketsTCP) Se crea el socket a partir de la dirección del
|
||||
* servidor (IP, puerto). La creación exitosa del socket significa que la
|
||||
* conexión TCP ha sido establecida.
|
||||
*/
|
||||
/*
|
||||
* TODO: (Boletín SocketsTCP) Se crean los DataInputStream/DataOutputStream a
|
||||
* done: (Boletín SocketsTCP) Se crean los DataInputStream/DataOutputStream a
|
||||
* partir de los streams de entrada/salida del socket creado. Se usarán para
|
||||
* enviar (dos) y recibir (dis) datos del servidor.
|
||||
*/
|
||||
|
||||
socket = new Socket(serverAddr.getAddress(), serverAddr.getPort());
|
||||
dis = new DataInputStream(socket.getInputStream());
|
||||
dos = new DataOutputStream(socket.getOutputStream());
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void test() {
|
||||
/*
|
||||
* TODO: (Boletín SocketsTCP) Enviar entero cualquiera a través del socket y
|
||||
* done: (Boletín SocketsTCP) Enviar entero cualquiera a través del socket y
|
||||
* después recibir otro entero, comprobando que se trata del mismo valor.
|
||||
*/
|
||||
/* double rand = Math.random() * 100;
|
||||
int intNumber = (int) rand;
|
||||
dos.writeInt(intNumber);
|
||||
System.out.println("sent " + intNumber);
|
||||
int newIntNumber = dis.readInt();
|
||||
System.out.println("received " + intNumber);
|
||||
*/
|
||||
try {
|
||||
PeerMessage msgOut = new PeerMessage(PeerMessageOps.OPCODE_REQUEST_PEER_FILES);
|
||||
msgOut.writeMessageToOutputStream(dos);
|
||||
System.out.println("sent " + PeerMessageOps.opcodeToOperation(msgOut.getOpcode()));
|
||||
PeerMessage msgIn = PeerMessage.readMessageFromInputStream(dis);
|
||||
System.out.println("received " + PeerMessageOps.opcodeToOperation(msgIn.getOpcode()));
|
||||
System.out.println("(" + new SimpleDateFormat("HH:mm:ss:SS").format(new Date()));
|
||||
if (msgIn.getOpcode() == PeerMessageOps.OPCODE_PEER_FILE) {
|
||||
System.out.println("file content: ");
|
||||
System.out.println("last = " + msgIn.getLast());
|
||||
System.out.println("fileSize = " + msgIn.getFileSize());
|
||||
System.out.println("hash = " + msgIn.getFileHash());
|
||||
System.out.println("long = " + msgIn.getFilenameLong());
|
||||
System.out.println("val = " + msgIn.getFilenameVal());
|
||||
}
|
||||
socket.close();
|
||||
} catch (IOException e) { e.printStackTrace(); }
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ public class PeerMessage {
|
||||
|
||||
|
||||
|
||||
|
||||
public static final byte HASH_LENGTH = 40;
|
||||
private byte opcode;
|
||||
|
||||
/*
|
||||
@@ -18,6 +18,11 @@ public class PeerMessage {
|
||||
* 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;
|
||||
|
||||
|
||||
|
||||
@@ -40,9 +45,49 @@ public class PeerMessage {
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Método de clase para parsear los campos de un mensaje y construir el objeto
|
||||
@@ -65,6 +110,31 @@ public class PeerMessage {
|
||||
PeerMessage message = new PeerMessage();
|
||||
byte opcode = dis.readByte();
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -87,6 +157,21 @@ public class PeerMessage {
|
||||
|
||||
dos.writeByte(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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,9 @@ public class PeerMessageOps {
|
||||
* los diferentes tipos de mensajes del protocolo de comunicación con un par
|
||||
* servidor de ficheros (valores posibles del campo "operation").
|
||||
*/
|
||||
|
||||
public static final byte OPCODE_REQUEST_PEER_FILES = 1;
|
||||
public static final byte OPCODE_PEER_FILE = 2;
|
||||
public static final byte OPCODE_PEER_FILES_ERROR = 3;
|
||||
|
||||
|
||||
|
||||
@@ -22,14 +24,14 @@ public class PeerMessageOps {
|
||||
* su representación textual a "valid_operations_str" EN EL MISMO ORDEN.
|
||||
*/
|
||||
private static final Byte[] _valid_opcodes = { OPCODE_INVALID_CODE,
|
||||
|
||||
|
||||
|
||||
OPCODE_REQUEST_PEER_FILES,
|
||||
OPCODE_PEER_FILE,
|
||||
OPCODE_PEER_FILES_ERROR
|
||||
};
|
||||
private static final String[] _valid_operations_str = { "INVALID_OPCODE",
|
||||
|
||||
|
||||
|
||||
"REQUEST_PEER_FILES",
|
||||
"PEER_FILE",
|
||||
"PEER_FILES_ERROR"
|
||||
};
|
||||
|
||||
private static Map<String, Byte> _operation_to_opcode;
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package es.um.redes.nanoFiles.tcp.server;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
|
||||
@@ -11,22 +14,26 @@ public class NFServer implements Runnable {
|
||||
|
||||
public static final int PORT = 10000;
|
||||
|
||||
|
||||
private NFServerState state = new NFServerState();
|
||||
|
||||
private ServerSocket serverSocket = null;
|
||||
|
||||
public ServerSocket getServerSocket() {
|
||||
return serverSocket;
|
||||
}
|
||||
|
||||
public NFServer() throws IOException {
|
||||
/*
|
||||
* TODO: (Boletín SocketsTCP) Crear una direción de socket a partir del puerto
|
||||
* done: (Boletín SocketsTCP) Crear una direción de socket a partir del puerto
|
||||
* especificado (PORT)
|
||||
*/
|
||||
/*
|
||||
* TODO: (Boletín SocketsTCP) Crear un socket servidor y ligarlo a la dirección
|
||||
* done: (Boletín SocketsTCP) Crear un socket servidor y ligarlo a la dirección
|
||||
* de socket anterior
|
||||
*/
|
||||
|
||||
|
||||
|
||||
InetSocketAddress serverSocketAddress = new InetSocketAddress(PORT);
|
||||
serverSocket = new ServerSocket();
|
||||
serverSocket.bind(serverSocketAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -47,16 +54,40 @@ public class NFServer implements Runnable {
|
||||
|
||||
while (true) {
|
||||
/*
|
||||
* TODO: (Boletín SocketsTCP) Usar el socket servidor para esperar conexiones de
|
||||
* done: (Boletín SocketsTCP) Usar el socket servidor para esperar conexiones de
|
||||
* otros peers que soliciten descargar ficheros.
|
||||
*/
|
||||
/*
|
||||
* TODO: (Boletín SocketsTCP) Tras aceptar la conexión con un peer cliente, la
|
||||
* done: (Boletín SocketsTCP) Tras aceptar la conexión con un peer cliente, la
|
||||
* comunicación con dicho cliente para servir los ficheros solicitados se debe
|
||||
* implementar en el método serveFilesToClient, al cual hay que pasarle el
|
||||
* socket devuelto por accept.
|
||||
*/
|
||||
boolean connectionOk = false;
|
||||
Socket socket = null;
|
||||
try {
|
||||
socket = serverSocket.accept();
|
||||
connectionOk = true;
|
||||
} catch (IOException e) {
|
||||
// conn refused
|
||||
}
|
||||
|
||||
if (connectionOk) {
|
||||
System.out.println("accepted");
|
||||
try {
|
||||
DataInputStream dis = new DataInputStream(socket.getInputStream());
|
||||
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
|
||||
|
||||
int intNumber = dis.readInt();
|
||||
System.out.println("received " + intNumber);
|
||||
|
||||
int newInt = intNumber + 1;
|
||||
dos.writeInt(newInt);
|
||||
System.out.println("sent " + newInt);
|
||||
} catch (IOException e) {
|
||||
// ???????
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -69,6 +100,7 @@ public class NFServer implements Runnable {
|
||||
* @see java.lang.Runnable#run()
|
||||
*/
|
||||
public void run() {
|
||||
boolean stopServer = false; // HAY QUE CAMBIAR ESTO PORQUE NO SÉ DE DÓNDE COJONES SALE (ver TODO l. 147)
|
||||
/*
|
||||
* TODO: (Boletín SocketsTCP) Usar el socket servidor para esperar conexiones de
|
||||
* otros peers que soliciten descargar ficheros
|
||||
@@ -88,6 +120,26 @@ public class NFServer implements Runnable {
|
||||
* más de un cliente conectado a este servidor.
|
||||
*/
|
||||
|
||||
while (!stopServer) {
|
||||
Socket socket = null;
|
||||
boolean connectionOk = false;
|
||||
try {
|
||||
socket = serverSocket.accept();
|
||||
connectionOk = true;
|
||||
} catch (IOException e) {
|
||||
System.err.println("Connection refused");
|
||||
}
|
||||
|
||||
if (connectionOk) {
|
||||
NFServerThread serverThread = new NFServerThread(socket, state);
|
||||
serverThread.start();
|
||||
int connNum = state.getNumberOfConnections();
|
||||
InetSocketAddress clientAddr = (InetSocketAddress) socket.getRemoteSocketAddress();
|
||||
System.out.println("New connection from " + clientAddr);
|
||||
System.out.println("Total connections = " + connNum);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -129,7 +181,15 @@ public class NFServer implements Runnable {
|
||||
* de su hash completo.
|
||||
*/
|
||||
|
||||
|
||||
InetSocketAddress clientAddr = (InetSocketAddress) socket.getRemoteSocketAddress();
|
||||
try {
|
||||
while(true) {
|
||||
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
|
||||
DataInputStream dis = new DataInputStream(socket.getInputStream());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
29
es/um/redes/nanoFiles/tcp/server/NFServerState.java
Normal file
29
es/um/redes/nanoFiles/tcp/server/NFServerState.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package es.um.redes.nanoFiles.tcp.server;
|
||||
|
||||
import java.net.Socket;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class NFServerState {
|
||||
private int numberOfConnections;
|
||||
private ArrayList<Socket> sockets;
|
||||
|
||||
public NFServerState() {
|
||||
numberOfConnections = 0;
|
||||
sockets = new ArrayList<>();
|
||||
}
|
||||
|
||||
public int getNumberOfConnections() {
|
||||
return numberOfConnections;
|
||||
}
|
||||
|
||||
public List<Socket> getSockets() {
|
||||
// tu puta madre va a hacer copias
|
||||
return sockets;
|
||||
}
|
||||
|
||||
public void updateState(Socket socket) {
|
||||
sockets.add(socket);
|
||||
numberOfConnections++;
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,15 @@ public class NFServerThread extends Thread {
|
||||
* (un socket distinto para "conversar" con un cliente)
|
||||
*/
|
||||
|
||||
private Socket socket;
|
||||
|
||||
public NFServerThread(Socket externalSocket, NFServerState state) {
|
||||
socket = externalSocket;
|
||||
state.updateState(socket);
|
||||
}
|
||||
|
||||
public void run() {
|
||||
NFServer.serveFilesToClient(socket);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -277,6 +277,19 @@ public class DirectoryConnector {
|
||||
|
||||
// TODO: Ver TODOs en pingDirectory y seguir esquema similar
|
||||
|
||||
/*
|
||||
* done: (Boletín MensajesASCII) Hacer ping al directorio 1.Crear el mensaje a
|
||||
* enviar (objeto DirMessage) con atributos adecuados (operation, etc.) NOTA:
|
||||
* Usar como operaciones las constantes definidas en la clase DirMessageOps :
|
||||
* 2.Convertir el objeto DirMessage a enviar a un string (método toString)
|
||||
* 3.Crear un datagrama con los bytes en que se codifica la cadena : 4.Enviar
|
||||
* datagrama y recibir una respuesta (sendAndReceiveDatagrams). : 5.Convertir
|
||||
* respuesta recibida en un objeto DirMessage (método DirMessage.fromString)
|
||||
* 6.Extraer datos del objeto DirMessage y procesarlos 7.Devolver éxito/fracaso
|
||||
* de la operación
|
||||
*/
|
||||
|
||||
DirMessage serve = new DirMessage(DirMessageOps.OPERATION_SERVE);
|
||||
|
||||
|
||||
return success;
|
||||
@@ -291,7 +304,11 @@ public class DirectoryConnector {
|
||||
*/
|
||||
public FileInfo[] getFileList() {
|
||||
FileInfo[] filelist = new FileInfo[0];
|
||||
// TODO: Ver TODOs en pingDirectory y seguir esquema similar
|
||||
DirMessage dirfiles = new DirMessage(DirMessageOps.OPERATION_DIRFILES);
|
||||
byte[] dirfilesBytes = dirfiles.toString().getBytes();
|
||||
byte[] resp = sendAndReceiveDatagrams(dirfilesBytes);
|
||||
|
||||
DirMessage respDirfiles = DirMessage.fromString(resp.toString());
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package es.um.redes.nanoFiles.udp.message;
|
||||
|
||||
import es.um.redes.nanoFiles.application.Directory;
|
||||
import es.um.redes.nanoFiles.application.NanoFiles;
|
||||
import es.um.redes.nanoFiles.util.FileInfo;
|
||||
|
||||
/**
|
||||
* Clase que modela los mensajes del protocolo de comunicación entre pares para
|
||||
@@ -26,6 +28,10 @@ public class DirMessage {
|
||||
* todos los campos que pueden aparecer en los mensajes de este protocolo
|
||||
* (formato campo:valor)
|
||||
*/
|
||||
private static final String FIELDNAME_FILENAME = "filename";
|
||||
private static final String FIELDNAME_FILESIZE = "size";
|
||||
private static final String FIELDNAME_FILEHASH = "hash";
|
||||
private static final String FIELDNAME_FILEPATH = "path";
|
||||
|
||||
private static final String FIELDNAME_PROTOCOL = "protocol";
|
||||
/**
|
||||
@@ -36,6 +42,7 @@ public class DirMessage {
|
||||
* Identificador de protocolo usado, para comprobar compatibilidad del directorio.
|
||||
*/
|
||||
private String protocolId;
|
||||
private FileInfo[] fileList;
|
||||
/*
|
||||
* TODO: (Boletín MensajesASCII) Crear un atributo correspondiente a cada uno de
|
||||
* los campos de los diferentes mensajes de este protocolo.
|
||||
@@ -45,6 +52,11 @@ public class DirMessage {
|
||||
operation = op;
|
||||
}
|
||||
|
||||
public DirMessage(String op, String nick, String ip, int puerto) {
|
||||
this(op);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: (Boletín MensajesASCII) Crear diferentes constructores adecuados para
|
||||
* construir mensajes de diferentes tipos con sus correspondientes argumentos
|
||||
@@ -70,12 +82,22 @@ public class DirMessage {
|
||||
}
|
||||
|
||||
public String getProtocolId() {
|
||||
|
||||
|
||||
|
||||
return protocolId;
|
||||
}
|
||||
|
||||
public FileInfo[] getFileList () {
|
||||
return fileList;
|
||||
}
|
||||
|
||||
public void setFileList(FileInfo f) {
|
||||
if (!operation.equals(DirMessageOps.OPERATION_REQUEST_DIRFILES)) {
|
||||
throw new RuntimeException (
|
||||
"DirMessage: setFileList called for message of type " + operation
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Método que convierte un mensaje codificado como una cadena de caracteres, a
|
||||
* un objeto de la clase PeerMessage, en el cual los atributos correspondientes
|
||||
@@ -86,6 +108,7 @@ public class DirMessage {
|
||||
* etc.)
|
||||
*/
|
||||
public static DirMessage fromString(String message) {
|
||||
System.out.println(message);
|
||||
/*
|
||||
* TODO: (Boletín MensajesASCII) Usar un bucle para parsear el mensaje línea a
|
||||
* línea, extrayendo para cada línea el nombre del campo y el valor, usando el
|
||||
@@ -96,7 +119,13 @@ public class DirMessage {
|
||||
String[] lines = message.split(END_LINE + "");
|
||||
// Local variables to save data during parsing
|
||||
DirMessage m = null;
|
||||
String filename = null;
|
||||
long filesize = 0;
|
||||
String filehash = null;
|
||||
String filepath = null;
|
||||
|
||||
// de alguna forma tengo que hacer un array de FileInfo
|
||||
// ArrayList y de ahí a array?
|
||||
for (String line : lines) {
|
||||
int idx = line.indexOf(DELIMITER); // Posición del delimitador
|
||||
String fieldName = line.substring(0, idx).toLowerCase(); // minúsculas
|
||||
@@ -114,6 +143,23 @@ public class DirMessage {
|
||||
break;
|
||||
}
|
||||
|
||||
case FIELDNAME_FILENAME: {
|
||||
filename = value;
|
||||
break;
|
||||
}
|
||||
|
||||
case FIELDNAME_FILESIZE: {
|
||||
filesize = Long.parseLong(value);
|
||||
break;
|
||||
}
|
||||
|
||||
case FIELDNAME_FILEHASH: {
|
||||
filehash = value;
|
||||
FileInfo f = new FileInfo(filehash, filename, filesize, filepath);
|
||||
// fileList += f;
|
||||
// y esto que, muchas gracias iniesta
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
System.err.println("PANIC: DirMessage.fromString - message with unknown field name " + fieldName);
|
||||
@@ -150,6 +196,16 @@ public class DirMessage {
|
||||
sb.append(FIELDNAME_PROTOCOL + DELIMITER + NanoFiles.PROTOCOL_ID + END_LINE);
|
||||
break;
|
||||
|
||||
case DirMessageOps.OPERATION_DIRFILES:
|
||||
FileInfo[] filelist = FileInfo.loadFilesFromFolder(Directory.DEFAULT_DIRECTORY_FILES_PATH);
|
||||
sb.append(FIELDNAME_OPERATION + DELIMITER + operation + END_LINE);
|
||||
for (FileInfo f : filelist) {
|
||||
sb.append(FIELDNAME_FILENAME + DELIMITER + f.fileName + END_LINE);
|
||||
sb.append(FIELDNAME_FILESIZE + DELIMITER + f.fileSize + END_LINE);
|
||||
sb.append(FIELDNAME_FILEHASH + DELIMITER + f.fileHash + END_LINE);
|
||||
sb.append(FIELDNAME_FILEPATH + DELIMITER + f.filePath + END_LINE);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,11 @@ public class DirMessageOps {
|
||||
|
||||
public static final String OPERATION_PING_OK = "pingOk";
|
||||
public static final String OPERATION_PING_BAD = "pingBad";
|
||||
|
||||
public static final String OPERATION_REQUEST_DIRFILES = "dirfiles";
|
||||
public static final String OPERATION_DIRFILES = "dirFilesList";
|
||||
|
||||
public static final String OPERATION_SERVE = "serve";
|
||||
// TODO: definir las operaciones del protocolo de directorio
|
||||
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import java.net.SocketException;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
import es.um.redes.nanoFiles.application.Directory;
|
||||
import es.um.redes.nanoFiles.application.NanoFiles;
|
||||
import es.um.redes.nanoFiles.udp.message.DirMessage;
|
||||
import es.um.redes.nanoFiles.udp.message.DirMessageOps;
|
||||
@@ -140,7 +141,7 @@ public class NFDirectoryServer {
|
||||
*/
|
||||
|
||||
/*
|
||||
* TODO: (Boletín Estructura-NanoFiles) Ampliar el código para que, en el caso
|
||||
* done: (Boletín Estructura-NanoFiles) Ampliar el código para que, en el caso
|
||||
* de que la cadena recibida no sea exactamente "ping", comprobar si comienza
|
||||
* por "ping&" (es del tipo "ping&PROTOCOL_ID", donde PROTOCOL_ID será el
|
||||
* identificador del protocolo diseñado por el grupo de prácticas (ver
|
||||
@@ -200,7 +201,7 @@ public class NFDirectoryServer {
|
||||
System.out.println("Hemos recibido: \n" + receivedData);
|
||||
DirMessage receivedMsg = DirMessage.fromString(receivedData);
|
||||
/*
|
||||
* TODO: Una vez construido un objeto DirMessage con el contenido del datagrama
|
||||
* done: Una vez construido un objeto DirMessage con el contenido del datagrama
|
||||
* recibido, obtener el tipo de operación solicitada por el mensaje y actuar en
|
||||
* consecuencia, enviando uno u otro tipo de mensaje en respuesta.
|
||||
*/
|
||||
@@ -236,20 +237,26 @@ public class NFDirectoryServer {
|
||||
* resultado del método.
|
||||
*/
|
||||
/*
|
||||
* TODO: (Boletín MensajesASCII) Imprimimos por pantalla el resultado de
|
||||
* done: (Boletín MensajesASCII) Imprimimos por pantalla el resultado de
|
||||
* procesar la petición recibida (éxito o fracaso) con los datos relevantes, a
|
||||
* modo de depuración en el servidor
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
case DirMessageOps.OPERATION_REQUEST_DIRFILES : {
|
||||
FileInfo[] filelist = FileInfo.loadFilesFromFolder(Directory.DEFAULT_DIRECTORY_FILES_PATH);
|
||||
operation = DirMessageOps.OPERATION_DIRFILES;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
System.err.println("Unexpected message operation: \"" + operation + "\"");
|
||||
System.exit(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: (Boletín MensajesASCII) Convertir a String el objeto DirMessage
|
||||
* done: (Boletín MensajesASCII) Convertir a String el objeto DirMessage
|
||||
* (msgToSend) con el mensaje de respuesta a enviar, extraer los bytes en que se
|
||||
* codifica el string y finalmente enviarlos en un datagrama
|
||||
*/
|
||||
|
||||
@@ -17,7 +17,7 @@ import es.um.redes.nanoFiles.shell.NFShell;
|
||||
* @author rtitos
|
||||
*
|
||||
* Utility class with static methods to abstract handling of file
|
||||
* metadata, loading shared failes, search by name substring, etc.
|
||||
* metadata, loading shared files, search by name substring, etc.
|
||||
*/
|
||||
public class FileInfo {
|
||||
public String fileHash;
|
||||
|
||||
Reference in New Issue
Block a user