From c0fb933fcee9dab5857310055e73249764b04b0d Mon Sep 17 00:00:00 2001 From: binlaab Date: Wed, 22 Apr 2026 11:53:24 +0200 Subject: [PATCH] =?UTF-8?q?Empezar=20bolet=C3=ADn=205,=20el=204=20est?= =?UTF-8?q?=C3=A1=20acabado?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nanoFiles/logic/NFControllerLogicDir.java | 2 - .../nanoFiles/logic/NFControllerLogicP2P.java | 5 +- .../udp/client/DirectoryConnector.java | 43 +++-- .../nanoFiles/udp/message/DirMessage.java | 177 +++++++++++++----- .../nanoFiles/udp/message/DirMessageOps.java | 5 + .../udp/server/NFDirectoryServer.java | 26 ++- 6 files changed, 192 insertions(+), 66 deletions(-) diff --git a/es/um/redes/nanoFiles/logic/NFControllerLogicDir.java b/es/um/redes/nanoFiles/logic/NFControllerLogicDir.java index 4746c95..3c74c28 100644 --- a/es/um/redes/nanoFiles/logic/NFControllerLogicDir.java +++ b/es/um/redes/nanoFiles/logic/NFControllerLogicDir.java @@ -130,8 +130,6 @@ public class NFControllerLogicDir { boolean result = false; if (this.directoryConnector.registerFileServer(serverPort)) { - - System.out.println("* File server successfully registered with the directory"); result = true; } else { diff --git a/es/um/redes/nanoFiles/logic/NFControllerLogicP2P.java b/es/um/redes/nanoFiles/logic/NFControllerLogicP2P.java index 2ee00ee..d86c3de 100644 --- a/es/um/redes/nanoFiles/logic/NFControllerLogicP2P.java +++ b/es/um/redes/nanoFiles/logic/NFControllerLogicP2P.java @@ -189,14 +189,15 @@ public class NFControllerLogicP2P { * @return El puerto en el que escucha el servidor, o 0 en caso de error. */ protected int getServerPort() { - int port = 0; + // int port = 0; + /* * TODO: Devolver el puerto de escucha de nuestro servidor de ficheros */ - return port; + return NFServer.PORT; } /** diff --git a/es/um/redes/nanoFiles/udp/client/DirectoryConnector.java b/es/um/redes/nanoFiles/udp/client/DirectoryConnector.java index 8411e45..67ea434 100644 --- a/es/um/redes/nanoFiles/udp/client/DirectoryConnector.java +++ b/es/um/redes/nanoFiles/udp/client/DirectoryConnector.java @@ -289,8 +289,16 @@ public class DirectoryConnector { * de la operación */ - DirMessage serve = new DirMessage(DirMessageOps.OPERATION_SERVE); - + DirMessage serve = new DirMessage(DirMessageOps.OPERATION_SERVE, NanoFiles.peerNickname, this.directoryHostname, serverPort); + byte[] serveBytes = serve.toString().getBytes(); + byte[] response = sendAndReceiveDatagrams(serveBytes); + String respStr = new String(response, 0, response.length); + DirMessage respServe= DirMessage.fromString(respStr); + success = respServe.getOperation().equals(DirMessageOps.OPERATION_SERVE_OK); + + if (success) { + + } return success; } @@ -303,24 +311,27 @@ public class DirectoryConnector { * pudo satisfacer nuestra solicitud */ public FileInfo[] getFileList() { - FileInfo[] filelist = new FileInfo[0]; - DirMessage dirfiles = new DirMessage(DirMessageOps.OPERATION_DIRFILES); - byte[] dirfilesBytes = dirfiles.toString().getBytes(); - byte[] resp = sendAndReceiveDatagrams(dirfilesBytes); + // tenemos que empezar a hacer con esta línea - DirMessage respDirfiles = DirMessage.fromString(resp.toString()); - - - - return filelist; + DirMessage requestDirfiles = new DirMessage(DirMessageOps.OPERATION_REQUEST_DIRFILES); + byte[] requestBytes = requestDirfiles.toString().getBytes(); + byte[] response = sendAndReceiveDatagrams(requestBytes); + + String respStr = new String(response, 0, response.length); + DirMessage respDirfiles = DirMessage.fromString(respStr); + return respDirfiles.getFileList(); + // return responseDirfiles.getFileList(); } public Map getPeerList() { - Map peers = new LinkedHashMap(); - - - - return peers; + // Map peers = new LinkedHashMap(); + DirMessage requestPeers = new DirMessage(DirMessageOps.OPERATION_REQUEST_SERVER_PEERS); + byte[] requestBytes = requestPeers.toString().getBytes(); + byte[] response = sendAndReceiveDatagrams(requestBytes); + + String respStr = new String(response, 0, response.length); + DirMessage respPeers = DirMessage.fromString(respStr); + return respPeers.getPeers(); } public Map searchFilesByHash(String hashSubstring) { diff --git a/es/um/redes/nanoFiles/udp/message/DirMessage.java b/es/um/redes/nanoFiles/udp/message/DirMessage.java index 92777f7..f0a2bc6 100644 --- a/es/um/redes/nanoFiles/udp/message/DirMessage.java +++ b/es/um/redes/nanoFiles/udp/message/DirMessage.java @@ -1,5 +1,9 @@ package es.um.redes.nanoFiles.udp.message; +import java.net.InetSocketAddress; +import java.util.LinkedHashMap; +import java.util.Map; + import es.um.redes.nanoFiles.application.Directory; import es.um.redes.nanoFiles.application.NanoFiles; import es.um.redes.nanoFiles.util.FileInfo; @@ -23,17 +27,22 @@ public class DirMessage { * Nombre del campo que define el tipo de mensaje (primera línea) */ private static final String FIELDNAME_OPERATION = "operation"; + /* * TODO: (Boletín MensajesASCII) Definir de manera simbólica los nombres de * 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"; + + private static final String FIELDNAME_NICK = "nick"; + private static final String FIELDNAME_IP = "ip"; + private static final String FIELDNAME_PORT = "port"; + + private static final String FIELDNAME_FILELIST = "filelist"; + + private static final String FIELDNAME_PEERS = "serverPeers"; + /** * Tipo del mensaje, de entre los tipos definidos en PeerMessageOps. */ @@ -42,7 +51,13 @@ public class DirMessage { * Identificador de protocolo usado, para comprobar compatibilidad del directorio. */ private String protocolId; + + private String nick; + private String ip; + private int port; + private FileInfo[] fileList; + private Map peerList; /* * TODO: (Boletín MensajesASCII) Crear un atributo correspondiente a cada uno de * los campos de los diferentes mensajes de este protocolo. @@ -54,8 +69,16 @@ public class DirMessage { public DirMessage(String op, String nick, String ip, int puerto) { this(op); + this.nick = nick; + this.ip = ip; + this.port = puerto; } + + public DirMessage(String op, FileInfo[] filelist) { + this(op); + this.fileList = filelist; + } /* * TODO: (Boletín MensajesASCII) Crear diferentes constructores adecuados para @@ -85,16 +108,48 @@ public class DirMessage { return protocolId; } - public FileInfo[] getFileList () { + 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 - ); + public void setFileList(FileInfo[] filelist) { + if (!operation.equals(DirMessageOps.OPERATION_DIRFILES)) { + throw new RuntimeException( + "DirMessage: setFileList called for message of unexpected type (" + operation + ")"); } + fileList = filelist; + } + + public String getNick() { + return nick; + } + + public String getIP() { + return ip; + } + + public int getPort() { + return port; + } + + public void setNick(String nick) { + this.nick = nick; + } + + public void setIP(String ip) { + this.ip = ip; + } + + public void setPort(int port) { + this.port = port; + } + + public Map getPeers() { + return this.peerList; + } + + public void setPeers(Map peers) { + this.peerList = peers; } @@ -108,7 +163,6 @@ 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 @@ -117,18 +171,13 @@ public class DirMessage { // System.out.println("DirMessage read from socket:"); // System.out.println(message); 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 + String fieldName = line.substring(0, idx); String value = line.substring(idx + 1).trim(); switch (fieldName) { @@ -143,23 +192,51 @@ public class DirMessage { break; } - case FIELDNAME_FILENAME: { - filename = value; + case FIELDNAME_NICK: { + System.out.println("nick"); + m.setNick(value); break; } - case FIELDNAME_FILESIZE: { - filesize = Long.parseLong(value); + case FIELDNAME_IP: { + System.out.println("ip"); + m.setIP(value); break; } - case FIELDNAME_FILEHASH: { - filehash = value; - FileInfo f = new FileInfo(filehash, filename, filesize, filepath); - // fileList += f; - // y esto que, muchas gracias iniesta + case FIELDNAME_PORT: { + System.out.println("port " + Integer.parseInt(value)); + m.setPort(Integer.parseInt(value)); + break; + } + + case FIELDNAME_FILELIST: { + String[] archivos = value.split(","); + FileInfo[] listaArchivos = new FileInfo[archivos.length]; + + for (int i = 0; i < archivos.length; i++) { + String[] atributos = archivos[i].split(":"); + FileInfo archivo = new FileInfo(atributos[2], atributos[0], Long.parseLong(atributos[1]), null); // de momento no meto el path + listaArchivos[i] = archivo; + } + + m.setFileList(listaArchivos); + break; + } + + case FIELDNAME_PEERS: { + System.out.println("Hemos entrado a FIELDNAME_PEERS"); + Map peersList = new LinkedHashMap<>(); + String[] peers = value.split(","); + for (String p: peers) { + String[] partes = p.split(":"); + peersList.put(partes[0], new InetSocketAddress(partes[1], Integer.parseInt(partes[2]))); + System.out.println("DirMessage - partes[0]: " + partes[0]); + } + + m.setPeers(peersList); + break; } - default: System.err.println("PANIC: DirMessage.fromString - message with unknown field name " + fieldName); @@ -167,10 +244,6 @@ public class DirMessage { System.exit(-1); } } - - - - return m; } @@ -181,6 +254,8 @@ public class DirMessage { * * @return La cadena de caracteres con el mensaje a enviar por el socket. */ + + // esto funciona tanto para el mensaje que entra (requestDirfiles, serve, etc.) como para el que sale (activateServeOk, dirfiles, etc.) public String toString() { StringBuffer sb = new StringBuffer(); @@ -195,20 +270,38 @@ public class DirMessage { case DirMessageOps.OPERATION_PING: sb.append(FIELDNAME_PROTOCOL + DELIMITER + NanoFiles.PROTOCOL_ID + END_LINE); break; - + + case DirMessageOps.OPERATION_SERVE: + sb.append(FIELDNAME_NICK + DELIMITER + this.nick + END_LINE); + sb.append(FIELDNAME_IP + DELIMITER + this.ip + END_LINE); + sb.append(FIELDNAME_PORT + DELIMITER + this.port + 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); + sb.append(FIELDNAME_FILELIST + DELIMITER); + for (int i = 0; i < fileList.length; i++) { + FileInfo f = fileList[i]; + sb.append(f.fileName + ':' + f.fileSize + ':' + f.fileHash); + if (i < fileList.length - 1) { + sb.append(','); // para evitar una coma al final + } + } + break; + + case DirMessageOps.OPERATION_SERVER_PEERS: + sb.append(FIELDNAME_PEERS + DELIMITER); + int nPeers = 0; + for (String nick : peerList.keySet()) { + sb.append(nick + ':' + peerList.get(nick).getHostString() + ':' + peerList.get(nick).getPort()); + if(nPeers++ < peerList.size()) { + sb.append(','); + } } break; default: break; } + sb.append(END_LINE); // Marcamos el final del mensaje return sb.toString(); } diff --git a/es/um/redes/nanoFiles/udp/message/DirMessageOps.java b/es/um/redes/nanoFiles/udp/message/DirMessageOps.java index 9708636..d96707c 100644 --- a/es/um/redes/nanoFiles/udp/message/DirMessageOps.java +++ b/es/um/redes/nanoFiles/udp/message/DirMessageOps.java @@ -17,6 +17,11 @@ public class DirMessageOps { public static final String OPERATION_DIRFILES = "dirFilesList"; public static final String OPERATION_SERVE = "serve"; + public static final String OPERATION_SERVE_OK = "activateServeOk"; + public static final String OPERATION_SERVE_ERROR = "activateServeError"; + + public static final String OPERATION_REQUEST_SERVER_PEERS = "peers"; + public static final String OPERATION_SERVER_PEERS = "serverPeers"; // TODO: definir las operaciones del protocolo de directorio diff --git a/es/um/redes/nanoFiles/udp/server/NFDirectoryServer.java b/es/um/redes/nanoFiles/udp/server/NFDirectoryServer.java index f5d5e9f..f7ccc0a 100644 --- a/es/um/redes/nanoFiles/udp/server/NFDirectoryServer.java +++ b/es/um/redes/nanoFiles/udp/server/NFDirectoryServer.java @@ -189,7 +189,7 @@ public class NFDirectoryServer { private void sendResponse(DatagramPacket pkt) throws IOException { /* - * TODO: (Boletín MensajesASCII) Construir String partir de los datos recibidos + * TODO?: (Boletín MensajesASCII) Construir String partir de los datos recibidos * en el datagrama pkt. A continuación, imprimir por pantalla dicha cadena a * modo de depuración. Después, usar la cadena para construir un objeto * DirMessage que contenga en sus atributos los valores del mensaje. A partir de @@ -209,6 +209,7 @@ public class NFDirectoryServer { if (receivedMsg != null) { operation = receivedMsg.getOperation(); } + DirMessage msgToSend = new DirMessage(DirMessageOps.OPERATION_INVALID); /* * TODO: (Boletín MensajesASCII) Construir un objeto DirMessage (msgToSend) con * la respuesta a enviar al cliente, en función del tipo de mensaje recibido, @@ -218,12 +219,14 @@ public class NFDirectoryServer { * enviar como respuesta (operation, etc.) */ switch (operation) { + // TODO: creo que hay getters y setters para esto????? case DirMessageOps.OPERATION_PING: { /* * done: (Boletín MensajesASCII) Comprobamos si el protocolId del mensaje del * cliente coincide con el nuestro. */ + msgToSend = new DirMessage(operation); String protocolId = receivedMsg.getProtocolId(); System.out.println(protocolId.equals(NanoFiles.PROTOCOL_ID)); if (protocolId.equals(NanoFiles.PROTOCOL_ID)) { @@ -245,10 +248,26 @@ public class NFDirectoryServer { } case DirMessageOps.OPERATION_REQUEST_DIRFILES : { - FileInfo[] filelist = FileInfo.loadFilesFromFolder(Directory.DEFAULT_DIRECTORY_FILES_PATH); - operation = DirMessageOps.OPERATION_DIRFILES; + msgToSend = new DirMessage(DirMessageOps.OPERATION_DIRFILES, this.directoryFiles); break; } + + case DirMessageOps.OPERATION_SERVE: { + + if (registeredPeers.put(receivedMsg.getNick(), new InetSocketAddress(receivedMsg.getIP(), receivedMsg.getPort())) == null) { + System.out.println("NFDS - añadido peer"); + msgToSend = new DirMessage(DirMessageOps.OPERATION_SERVE_OK); + } else { + msgToSend = new DirMessage(DirMessageOps.OPERATION_SERVE_ERROR); + } + break; + } + + case DirMessageOps.OPERATION_REQUEST_SERVER_PEERS: { + msgToSend = new DirMessage(DirMessageOps.OPERATION_SERVER_PEERS); + msgToSend.setPeers(registeredPeers); + break; + } default: System.err.println("Unexpected message operation: \"" + operation + "\""); @@ -260,7 +279,6 @@ public class NFDirectoryServer { * (msgToSend) con el mensaje de respuesta a enviar, extraer los bytes en que se * codifica el string y finalmente enviarlos en un datagrama */ - DirMessage msgToSend = new DirMessage(operation); String msgToSendStr = msgToSend.toString(); byte[] dataToSend = msgToSendStr.getBytes(); InetSocketAddress clientAddr = (InetSocketAddress) pkt.getSocketAddress();