mirror of
https://github.com/binlaab/nanofiles.git
synced 2026-07-01 18:46:33 +02:00
empezada implementación peerdl, cambiar DEFAULT_DIRECTORY_HOSTNAME en NanoFiles
This commit is contained in:
@@ -12,7 +12,7 @@ public class NanoFiles {
|
|||||||
* que combine los DNIs de ambos miembros del grupo de prácticas.
|
* que combine los DNIs de ambos miembros del grupo de prácticas.
|
||||||
*/
|
*/
|
||||||
public static final String PROTOCOL_ID = "123456789A";
|
public static final String PROTOCOL_ID = "123456789A";
|
||||||
private static final String DEFAULT_DIRECTORY_HOSTNAME = "localhost";
|
private static final String DEFAULT_DIRECTORY_HOSTNAME = "192.168.126.1";
|
||||||
public static String sharedDirname = DEFAULT_SHARED_DIRNAME;
|
public static String sharedDirname = DEFAULT_SHARED_DIRNAME;
|
||||||
public static FileDatabase db;
|
public static FileDatabase db;
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -2,16 +2,22 @@ package es.um.redes.nanoFiles.logic;
|
|||||||
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.ServerSocket;
|
import java.net.ServerSocket;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.RandomAccessFile;
|
||||||
|
|
||||||
import es.um.redes.nanoFiles.tcp.client.NFConnector;
|
import es.um.redes.nanoFiles.tcp.client.NFConnector;
|
||||||
import es.um.redes.nanoFiles.application.NanoFiles;
|
import es.um.redes.nanoFiles.application.NanoFiles;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import es.um.redes.nanoFiles.tcp.server.NFServer;
|
import es.um.redes.nanoFiles.tcp.server.NFServer;
|
||||||
|
import es.um.redes.nanoFiles.udp.client.DirectoryConnector;
|
||||||
|
import es.um.redes.nanoFiles.util.FileDigest;
|
||||||
import es.um.redes.nanoFiles.util.FileInfo;
|
import es.um.redes.nanoFiles.util.FileInfo;
|
||||||
|
import es.um.redes.nanoFiles.util.FileNameUtil;
|
||||||
|
|
||||||
public class NFControllerLogicP2P {
|
public class NFControllerLogicP2P {
|
||||||
// Servidor TCP local para compartir ficheros con otros peers
|
// Servidor TCP local para compartir ficheros con otros peers
|
||||||
@@ -159,34 +165,33 @@ public class NFControllerLogicP2P {
|
|||||||
// TODO: localizar peers con el hash solicitado (o uno concreto) y delegar en
|
// TODO: localizar peers con el hash solicitado (o uno concreto) y delegar en
|
||||||
// downloadFileFromServers
|
// downloadFileFromServers
|
||||||
boolean success = false;
|
boolean success = false;
|
||||||
LinkedList<InetSocketAddress> peersWithFile = new LinkedList<>();
|
if (targetPeerNickname == "*") {
|
||||||
Map<String, InetSocketAddress> peers = dirLogic.fetchPeerList();
|
Map<String, InetSocketAddress[]> peersWithFile = new HashMap<String, InetSocketAddress[]>();
|
||||||
|
|
||||||
LinkedList<InetSocketAddress> targets = new LinkedList<>();
|
|
||||||
|
|
||||||
/* if (targetPeerNickname == "*") { bloqueado de momento
|
|
||||||
targets.addAll(peers.values());
|
|
||||||
} else { */
|
|
||||||
targets.add(peers.get(targetPeerNickname));
|
|
||||||
// }
|
|
||||||
|
|
||||||
for (InetSocketAddress addr : targets) {
|
|
||||||
try {
|
try {
|
||||||
NFConnector nfc = new NFConnector(addr);
|
DirectoryConnector dc = new DirectoryConnector(dirLogic.getDirectoryHostname()); // la verdad que debería poder sacarlo de dirLogic
|
||||||
|
peersWithFile = dc.searchFilesByHash(targetHashSubstring);
|
||||||
|
|
||||||
|
} catch (IOException e) { e.printStackTrace(); }
|
||||||
|
success = downloadFileFromServers(peersWithFile.values().iterator().next(), peersWithFile.keySet().iterator().next()); // dios
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
InetSocketAddress[] peerAddr = new InetSocketAddress[] {dirLogic.fetchPeerList().get(targetPeerNickname)};
|
||||||
|
NFConnector nfc = new NFConnector(peerAddr[0]);
|
||||||
FileInfo[] peerFiles = nfc.getFileList();
|
FileInfo[] peerFiles = nfc.getFileList();
|
||||||
|
|
||||||
// la longitud tiene que ser EXACTAMENTE 1, si es 0 no hay, si es > 1 es ambiguo
|
FileInfo[] found = FileInfo.lookupHashSubstring(peerFiles, targetHashSubstring);
|
||||||
// y si resulta que dos peers tienen un mismo subhash sin tener el mismo hash?
|
if (found.length > 1) {
|
||||||
// mando que no se ha podido descargar? comparo contra el hash del primero?
|
System.err.println("The hash substring provided is ambiguous");
|
||||||
FileInfo[] peerFilesFound = FileInfo.lookupHashSubstring(peerFiles, targetHashSubstring);
|
return success;
|
||||||
if (peerFilesFound.length == 1) {
|
} else if (found.length == 0) {
|
||||||
peersWithFile.add(addr);
|
System.err.println("The hash substring provided could not be found in peer " + targetPeerNickname);
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
success = downloadFileFromServers(peerAddr, found[0].fileHash); // voy a darle el hash entero, más fácil que volver a buscarlo
|
||||||
} catch (IOException e) { e.printStackTrace(); }
|
} catch (IOException e) { e.printStackTrace(); }
|
||||||
|
System.out.println("Hemos descargado algo? success = " + success);
|
||||||
}
|
}
|
||||||
|
|
||||||
success = downloadFileFromServers(peersWithFile.toArray(new InetSocketAddress[0]), targetHashSubstring);
|
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@@ -196,7 +201,7 @@ public class NFControllerLogicP2P {
|
|||||||
* que se conectará
|
* que se conectará
|
||||||
* @param targetHashSubstring Subcadena del hash del fichero a descargar
|
* @param targetHashSubstring Subcadena del hash del fichero a descargar
|
||||||
*/
|
*/
|
||||||
protected boolean downloadFileFromServers(InetSocketAddress[] serverAddressList, String targetHashSubstring) {
|
protected boolean downloadFileFromServers(InetSocketAddress[] serverAddressList, String targetHash) {
|
||||||
boolean downloaded = false;
|
boolean downloaded = false;
|
||||||
|
|
||||||
if (serverAddressList.length == 0) {
|
if (serverAddressList.length == 0) {
|
||||||
@@ -207,14 +212,42 @@ public class NFControllerLogicP2P {
|
|||||||
// pedido, obtener nombre remoto, reservar nombre local sin colisiones, alternar
|
// pedido, obtener nombre remoto, reservar nombre local sin colisiones, alternar
|
||||||
// descarga de chunks y verificar hash final. Cerrar los sockets al terminar.
|
// descarga de chunks y verificar hash final. Cerrar los sockets al terminar.
|
||||||
|
|
||||||
|
|
||||||
|
long filesize = -1;
|
||||||
|
String filename = "";
|
||||||
|
|
||||||
NFConnector[] peerConns = new NFConnector[serverAddressList.length];
|
NFConnector[] peerConns = new NFConnector[serverAddressList.length];
|
||||||
|
|
||||||
for (int i = 0; i < serverAddressList.length; i++) {
|
for (int i = 0; i < serverAddressList.length; i++) {
|
||||||
try {
|
try {
|
||||||
NFConnector nfc = new NFConnector(serverAddressList[i]);
|
NFConnector nfc = new NFConnector(serverAddressList[i]);
|
||||||
|
if (filesize == -1) {
|
||||||
|
FileInfo[] files = nfc.getFileList();
|
||||||
|
FileInfo fileToDownload = FileInfo.lookupHashSubstring(files, targetHash)[0]; // espero solo un archivo
|
||||||
|
filesize = fileToDownload.fileSize;
|
||||||
|
filename = toDisplayPath(FileNameUtil.chooseAvailableName(fileToDownload.fileName));
|
||||||
|
}
|
||||||
peerConns[i] = nfc;
|
peerConns[i] = nfc;
|
||||||
} catch (IOException e) { e.printStackTrace(); }
|
} catch (IOException e) { e.printStackTrace(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
try (RandomAccessFile raf = new RandomAccessFile(NanoFiles.sharedDirname + "/" + filename, "rw")) {
|
||||||
|
raf.setLength(filesize);
|
||||||
|
int chunks = (int) Math.ceil((double) filesize / NFConnector.CHUNK_SIZE);
|
||||||
|
|
||||||
|
for (int i = 0; i < chunks; i++) {
|
||||||
|
NFConnector nfc = peerConns[i % peerConns.length];
|
||||||
|
if (!nfc.downloadChunk(targetHash, i, raf)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
downloaded = true;
|
||||||
|
} catch (IOException e) { e.printStackTrace(); }
|
||||||
|
|
||||||
|
downloaded = targetHash.equals(FileDigest.computeFileChecksumString(NanoFiles.sharedDirname + "/" + filename));
|
||||||
|
|
||||||
return downloaded;
|
return downloaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ public class NFConnector {
|
|||||||
private Socket socket;
|
private Socket socket;
|
||||||
private InetSocketAddress serverAddr;
|
private InetSocketAddress serverAddr;
|
||||||
|
|
||||||
|
public static final int CHUNK_SIZE = 64 * 1024; // 64 kB máx
|
||||||
|
|
||||||
private DataInputStream dis;
|
private DataInputStream dis;
|
||||||
private DataOutputStream dos;
|
private DataOutputStream dos;
|
||||||
@@ -84,7 +85,9 @@ public class NFConnector {
|
|||||||
LinkedList<FileInfo> filelist = new LinkedList<>();
|
LinkedList<FileInfo> filelist = new LinkedList<>();
|
||||||
PeerMessage msgOut = new PeerMessage(PeerMessageOps.OPCODE_REQUEST_PEER_FILES);
|
PeerMessage msgOut = new PeerMessage(PeerMessageOps.OPCODE_REQUEST_PEER_FILES);
|
||||||
msgOut.writeMessageToOutputStream(dos);
|
msgOut.writeMessageToOutputStream(dos);
|
||||||
|
System.out.println("gfl enviado");
|
||||||
PeerMessage msgIn = PeerMessage.readMessageFromInputStream(dis);
|
PeerMessage msgIn = PeerMessage.readMessageFromInputStream(dis);
|
||||||
|
System.out.println("gfl leido");
|
||||||
if (msgIn.getOpcode() == PeerMessageOps.OPCODE_PEER_FILE) {
|
if (msgIn.getOpcode() == PeerMessageOps.OPCODE_PEER_FILE) {
|
||||||
boolean last = false;
|
boolean last = false;
|
||||||
while (!last) {
|
while (!last) {
|
||||||
@@ -94,30 +97,40 @@ public class NFConnector {
|
|||||||
FileInfo file = new FileInfo(hash, name, size, null);
|
FileInfo file = new FileInfo(hash, name, size, null);
|
||||||
filelist.add(file);
|
filelist.add(file);
|
||||||
last = msgIn.getLast();
|
last = msgIn.getLast();
|
||||||
|
System.out.println("Tenemos otro archivo, last = " + last);
|
||||||
if (!last) msgIn = PeerMessage.readMessageFromInputStream(dis); // tengo que ver si puedo hacerlo diferente
|
if (!last) msgIn = PeerMessage.readMessageFromInputStream(dis); // tengo que ver si puedo hacerlo diferente
|
||||||
}
|
}
|
||||||
} else { return null; }
|
} else { return null; }
|
||||||
|
System.out.println("Nos vamos de gfl");
|
||||||
return filelist.toArray(new FileInfo[0]);
|
return filelist.toArray(new FileInfo[0]);
|
||||||
} catch (IOException e) { e.printStackTrace(); return null; }
|
} catch (IOException e) { e.printStackTrace(); return null; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] downloadChunk(String hash, int chunkNum) {
|
public boolean downloadChunk(String hash, int chunkNum, RandomAccessFile raf) {
|
||||||
|
boolean success = false;
|
||||||
try {
|
try {
|
||||||
PeerMessage msgOut = new PeerMessage(PeerMessageOps.OPCODE_REQUEST_PEER_DL);
|
PeerMessage msgOut = new PeerMessage(PeerMessageOps.OPCODE_REQUEST_PEER_DL);
|
||||||
msgOut.setFileHash(hash);
|
msgOut.setFileHash(hash);
|
||||||
msgOut.setChunkNum(chunkNum);
|
msgOut.setChunkNum(chunkNum);
|
||||||
|
|
||||||
msgOut.writeMessageToOutputStream(dos);
|
msgOut.writeMessageToOutputStream(dos);
|
||||||
|
|
||||||
PeerMessage msgIn = PeerMessage.readMessageFromInputStream(dis);
|
PeerMessage msgIn = PeerMessage.readMessageFromInputStream(dis);
|
||||||
|
|
||||||
if (msgIn.getOpcode() == PeerMessageOps.OPCODE_PEER_DL) {
|
if (msgIn.getOpcode() == PeerMessageOps.OPCODE_PEER_DL) {
|
||||||
return msgIn.getFileData();
|
byte[] datos = msgIn.getFileData();
|
||||||
|
raf.seek((long) chunkNum * CHUNK_SIZE); // buscamos el trozo que estamos leyendo
|
||||||
|
raf.write(datos);
|
||||||
|
success = true;
|
||||||
|
|
||||||
|
} else if (msgIn.getOpcode() == PeerMessageOps.OPCODE_AMBIGUOUS) {
|
||||||
|
System.err.println("More than one file exists with this hash substring");
|
||||||
|
} else if (msgIn.getOpcode() == PeerMessageOps.OPCODE_FILE_NOT_FOUND) {
|
||||||
|
System.err.println("No file matches the hash substring");
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (IOException e) { e.printStackTrace(); }
|
} catch (IOException e) { e.printStackTrace(); }
|
||||||
|
|
||||||
return null;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InetSocketAddress getServerAddr() {
|
public InetSocketAddress getServerAddr() {
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ public class PeerMessage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setFilenameVal(String filenameVal) {
|
public void setFilenameVal(String filenameVal) {
|
||||||
|
this.filenameLong = (byte) filenameVal.length();
|
||||||
this.filenameVal = filenameVal;
|
this.filenameVal = filenameVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,6 +131,8 @@ public class PeerMessage {
|
|||||||
PeerMessage message = new PeerMessage(opcode);
|
PeerMessage message = new PeerMessage(opcode);
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case PeerMessageOps.OPCODE_REQUEST_PEER_FILES:
|
case PeerMessageOps.OPCODE_REQUEST_PEER_FILES:
|
||||||
|
case PeerMessageOps.OPCODE_FILE_NOT_FOUND:
|
||||||
|
case PeerMessageOps.OPCODE_AMBIGUOUS:
|
||||||
case PeerMessageOps.OPCODE_PEER_FILES_ERROR: break;
|
case PeerMessageOps.OPCODE_PEER_FILES_ERROR: break;
|
||||||
case PeerMessageOps.OPCODE_PEER_FILE: {
|
case PeerMessageOps.OPCODE_PEER_FILE: {
|
||||||
|
|
||||||
@@ -137,6 +140,7 @@ public class PeerMessage {
|
|||||||
byte lastVal = dis.readByte();
|
byte lastVal = dis.readByte();
|
||||||
|
|
||||||
if (lastVal == 1) {
|
if (lastVal == 1) {
|
||||||
|
System.out.println("rmfis - last = " + last);
|
||||||
last = true;
|
last = true;
|
||||||
}
|
}
|
||||||
long fileSize = dis.readLong();
|
long fileSize = dis.readLong();
|
||||||
@@ -158,19 +162,22 @@ public class PeerMessage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case PeerMessageOps.OPCODE_REQUEST_PEER_DL: {
|
case PeerMessageOps.OPCODE_REQUEST_PEER_DL: {
|
||||||
// buscar archivo supongo
|
|
||||||
}
|
|
||||||
case PeerMessageOps.OPCODE_PEER_DL: {
|
|
||||||
int longitudSubHash = (int) dis.readByte();
|
int longitudSubHash = (int) dis.readByte();
|
||||||
byte[] subHash = new byte[longitudSubHash];
|
byte[] subHash = new byte[longitudSubHash];
|
||||||
dis.readFully(subHash);
|
dis.readFully(subHash);
|
||||||
|
|
||||||
|
message.setFileHash(new String(subHash));
|
||||||
|
message.setChunkNum(dis.readInt());
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case PeerMessageOps.OPCODE_PEER_DL: {
|
||||||
|
int length = dis.readInt();
|
||||||
|
byte[] datos = new byte[length];
|
||||||
|
dis.readFully(datos);
|
||||||
|
message.setFileData(datos);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
System.err.println("PeerMessage.readMessageFromInputStream doesn't know how to parse this message opcode: "
|
System.err.println("PeerMessage.readMessageFromInputStream doesn't know how to parse this message opcode: "
|
||||||
@@ -193,6 +200,8 @@ public class PeerMessage {
|
|||||||
System.out.println(opcode);
|
System.out.println(opcode);
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case PeerMessageOps.OPCODE_REQUEST_PEER_FILES:
|
case PeerMessageOps.OPCODE_REQUEST_PEER_FILES:
|
||||||
|
case PeerMessageOps.OPCODE_FILE_NOT_FOUND:
|
||||||
|
case PeerMessageOps.OPCODE_AMBIGUOUS:
|
||||||
case PeerMessageOps.OPCODE_PEER_FILES_ERROR: break;
|
case PeerMessageOps.OPCODE_PEER_FILES_ERROR: break;
|
||||||
case PeerMessageOps.OPCODE_PEER_FILE: {
|
case PeerMessageOps.OPCODE_PEER_FILE: {
|
||||||
byte lastVal = 0;
|
byte lastVal = 0;
|
||||||
@@ -208,8 +217,19 @@ public class PeerMessage {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case PeerMessageOps.OPCODE_REQUEST_PEER_DL: {
|
||||||
|
byte[] hash = fileHash.getBytes();
|
||||||
|
dos.writeByte((byte) hash.length);
|
||||||
|
dos.write(hash);
|
||||||
|
dos.writeInt(chunkNum);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case PeerMessageOps.OPCODE_PEER_DL: {
|
||||||
|
dos.writeInt(fileData.length);
|
||||||
|
dos.write(fileData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
System.err.println("PeerMessage.writeMessageToOutputStream found unexpected message opcode " + opcode + "("
|
System.err.println("PeerMessage.writeMessageToOutputStream found unexpected message opcode " + opcode + "("
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ public class PeerMessageOps {
|
|||||||
public static final byte OPCODE_FILE_NOT_FOUND = 5;
|
public static final byte OPCODE_FILE_NOT_FOUND = 5;
|
||||||
public static final byte OPCODE_AMBIGUOUS = 6;
|
public static final byte OPCODE_AMBIGUOUS = 6;
|
||||||
public static final byte OPCODE_PEER_DL = 7;
|
public static final byte OPCODE_PEER_DL = 7;
|
||||||
|
public static final byte OPCODE_PEER_DL_ERROR = 8;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -36,7 +37,8 @@ public class PeerMessageOps {
|
|||||||
OPCODE_REQUEST_PEER_DL,
|
OPCODE_REQUEST_PEER_DL,
|
||||||
OPCODE_FILE_NOT_FOUND,
|
OPCODE_FILE_NOT_FOUND,
|
||||||
OPCODE_AMBIGUOUS,
|
OPCODE_AMBIGUOUS,
|
||||||
OPCODE_PEER_DL
|
OPCODE_PEER_DL,
|
||||||
|
OPCODE_PEER_DL_ERROR
|
||||||
};
|
};
|
||||||
private static final String[] _valid_operations_str = { "INVALID_OPCODE",
|
private static final String[] _valid_operations_str = { "INVALID_OPCODE",
|
||||||
"REQUEST_PEER_FILES",
|
"REQUEST_PEER_FILES",
|
||||||
@@ -45,7 +47,8 @@ public class PeerMessageOps {
|
|||||||
"REQUEST_PEER_DL",
|
"REQUEST_PEER_DL",
|
||||||
"FILE_NOT_FOUND",
|
"FILE_NOT_FOUND",
|
||||||
"FILE_AMBIGUOUS",
|
"FILE_AMBIGUOUS",
|
||||||
"PEER_DL"
|
"PEER_DL",
|
||||||
|
"PEER_DL_ERROR"
|
||||||
};
|
};
|
||||||
|
|
||||||
private static Map<String, Byte> _operation_to_opcode;
|
private static Map<String, Byte> _operation_to_opcode;
|
||||||
|
|||||||
@@ -3,11 +3,13 @@ package es.um.redes.nanoFiles.tcp.server;
|
|||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.RandomAccessFile;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.ServerSocket;
|
import java.net.ServerSocket;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
|
||||||
import es.um.redes.nanoFiles.application.NanoFiles;
|
import es.um.redes.nanoFiles.application.NanoFiles;
|
||||||
|
import es.um.redes.nanoFiles.tcp.client.NFConnector;
|
||||||
import es.um.redes.nanoFiles.tcp.message.PeerMessage;
|
import es.um.redes.nanoFiles.tcp.message.PeerMessage;
|
||||||
import es.um.redes.nanoFiles.tcp.message.PeerMessageOps;
|
import es.um.redes.nanoFiles.tcp.message.PeerMessageOps;
|
||||||
import es.um.redes.nanoFiles.util.FileInfo;
|
import es.um.redes.nanoFiles.util.FileInfo;
|
||||||
@@ -104,7 +106,7 @@ public class NFServer implements Runnable {
|
|||||||
System.out.println("sent " + PeerMessageOps.opcodeToOperation(msgOut.getOpcode()));
|
System.out.println("sent " + PeerMessageOps.opcodeToOperation(msgOut.getOpcode()));
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// ???????
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,24 +209,62 @@ public class NFServer implements Runnable {
|
|||||||
while(true) {
|
while(true) {
|
||||||
|
|
||||||
PeerMessage msgIn = PeerMessage.readMessageFromInputStream(dis);
|
PeerMessage msgIn = PeerMessage.readMessageFromInputStream(dis);
|
||||||
|
System.out.println("nfserver - " + msgIn.getOpcode());
|
||||||
switch (msgIn.getOpcode()) {
|
switch (msgIn.getOpcode()) {
|
||||||
case PeerMessageOps.OPCODE_REQUEST_PEER_FILES:
|
case PeerMessageOps.OPCODE_REQUEST_PEER_FILES:
|
||||||
|
System.out.println("hemos llegado a nfserver");
|
||||||
|
|
||||||
FileInfo[] archivos = NanoFiles.db.getFiles();
|
FileInfo[] archivos = NanoFiles.db.getFiles();
|
||||||
|
|
||||||
for (int i = 0; i < archivos.length; i++) {
|
for (int i = 0; i < archivos.length; i++) {
|
||||||
PeerMessage msgOut = new PeerMessage(PeerMessageOps.OPCODE_PEER_FILE);
|
PeerMessage msgOut = new PeerMessage(PeerMessageOps.OPCODE_PEER_FILE);
|
||||||
FileInfo archivo = archivos[i];
|
FileInfo archivo = archivos[i];
|
||||||
|
System.out.println("Tenemos una lista de archivos de " + archivos.length);
|
||||||
msgOut.setFileHash(archivo.fileHash);
|
msgOut.setFileHash(archivo.fileHash);
|
||||||
msgOut.setFileSize(archivo.fileSize);
|
msgOut.setFileSize(archivo.fileSize);
|
||||||
msgOut.setFilenameVal(archivo.filePath + archivo.fileName);
|
msgOut.setFilenameVal(archivo.fileName);
|
||||||
msgOut.setFilenameLong((byte)archivo.fileName.length());
|
|
||||||
msgOut.setLast(false);
|
msgOut.setLast(false);
|
||||||
if (i == archivos.length - 1) msgOut.setLast(true);
|
if (i == archivos.length - 1) { msgOut.setLast(true); System.out.println("Hemos llegado al último archivo"); };
|
||||||
msgOut.writeMessageToOutputStream(dos);
|
msgOut.writeMessageToOutputStream(dos);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PeerMessageOps.OPCODE_REQUEST_PEER_DL:
|
||||||
|
String subHash = msgIn.getFileHash();
|
||||||
|
int chunkNum = msgIn.getChunkNum();
|
||||||
|
FileInfo[] files = FileInfo.lookupHashSubstring(NanoFiles.db.getFiles(), subHash);
|
||||||
|
|
||||||
|
if (files.length == 0) {
|
||||||
|
PeerMessage msgOut = new PeerMessage(PeerMessageOps.OPCODE_FILE_NOT_FOUND);
|
||||||
|
msgOut.writeMessageToOutputStream(dos);
|
||||||
|
break;
|
||||||
|
} else if (files.length > 1) {
|
||||||
|
PeerMessage msgOut = new PeerMessage(PeerMessageOps.OPCODE_AMBIGUOUS);
|
||||||
|
msgOut.writeMessageToOutputStream(dos);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
String path = NanoFiles.db.lookupFilePath(files[0].fileHash);
|
||||||
|
try (RandomAccessFile raf = new RandomAccessFile(path, "r")) {
|
||||||
|
long chunk = (long) chunkNum * NFConnector.CHUNK_SIZE;
|
||||||
|
int bytesALeer = (int) Math.min(NFConnector.CHUNK_SIZE, raf.length() - chunk);
|
||||||
|
// si quedan menos de CHUNK_SIZE bytes restantes, readFully se quedaría esperando
|
||||||
|
// a rellenar el buffer, lo cual no va a pasar
|
||||||
|
|
||||||
|
if (bytesALeer > 0) {
|
||||||
|
byte[] datos = new byte[bytesALeer];
|
||||||
|
raf.seek(chunk);
|
||||||
|
raf.readFully(datos);
|
||||||
|
|
||||||
|
PeerMessage msgOut = new PeerMessage(PeerMessageOps.OPCODE_PEER_DL);
|
||||||
|
msgOut.setFileData(datos);
|
||||||
|
msgOut.writeMessageToOutputStream(dos);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
PeerMessage msgOut = new PeerMessage(PeerMessageOps.OPCODE_PEER_DL_ERROR);
|
||||||
|
msgOut.writeMessageToOutputStream(dos);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import java.net.InetAddress;
|
|||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.SocketTimeoutException;
|
import java.net.SocketTimeoutException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import es.um.redes.nanoFiles.tcp.client.NFConnector;
|
import es.um.redes.nanoFiles.tcp.client.NFConnector;
|
||||||
|
|
||||||
@@ -80,7 +81,7 @@ public class DirectoryConnector {
|
|||||||
* datagramas al directorio
|
* datagramas al directorio
|
||||||
*/
|
*/
|
||||||
directoryAddress = new InetSocketAddress(InetAddress.getByName(hostname), DIRECTORY_PORT);
|
directoryAddress = new InetSocketAddress(InetAddress.getByName(hostname), DIRECTORY_PORT);
|
||||||
socket = new DatagramSocket(6767);
|
socket = new DatagramSocket();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -291,18 +292,19 @@ public class DirectoryConnector {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// este trozo hay que cambiarlo porque qué cojones
|
// este trozo hay que cambiarlo porque qué cojones
|
||||||
|
// encima tiene algo mal
|
||||||
String ip = null;
|
String ip = null;
|
||||||
try {
|
try {
|
||||||
socket.connect(directoryAddress);
|
socket.connect(directoryAddress);
|
||||||
ip = socket.getLocalAddress().getHostAddress();
|
ip = socket.getLocalAddress().getHostAddress();
|
||||||
socket.disconnect();
|
socket.disconnect();
|
||||||
} catch(Exception e) {}
|
} catch (Exception e) {}
|
||||||
|
|
||||||
DirMessage serve = new DirMessage(DirMessageOps.OPERATION_SERVE, NanoFiles.peerNickname, ip, serverPort);
|
DirMessage serve = new DirMessage(DirMessageOps.OPERATION_SERVE, NanoFiles.peerNickname, ip, serverPort);
|
||||||
byte[] serveBytes = serve.toString().getBytes();
|
byte[] serveBytes = serve.toString().getBytes();
|
||||||
byte[] response = sendAndReceiveDatagrams(serveBytes);
|
byte[] response = sendAndReceiveDatagrams(serveBytes);
|
||||||
String respStr = new String(response, 0, response.length);
|
String respStr = new String(response, 0, response.length);
|
||||||
DirMessage respServe= DirMessage.fromString(respStr);
|
DirMessage respServe = DirMessage.fromString(respStr);
|
||||||
success = respServe.getOperation().equals(DirMessageOps.OPERATION_SERVE_OK);
|
success = respServe.getOperation().equals(DirMessageOps.OPERATION_SERVE_OK);
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
@@ -346,8 +348,33 @@ public class DirectoryConnector {
|
|||||||
public Map<String, InetSocketAddress[]> searchFilesByHash(String hashSubstring) {
|
public Map<String, InetSocketAddress[]> searchFilesByHash(String hashSubstring) {
|
||||||
Map<String, InetSocketAddress[]> results = new LinkedHashMap<String, InetSocketAddress[]>();
|
Map<String, InetSocketAddress[]> results = new LinkedHashMap<String, InetSocketAddress[]>();
|
||||||
|
|
||||||
|
Map<String, InetSocketAddress> peers = getPeerList();
|
||||||
|
|
||||||
|
for (InetSocketAddress addr : peers.values()) {
|
||||||
|
try {
|
||||||
|
NFConnector nfc = new NFConnector(addr);
|
||||||
|
FileInfo[] peerFiles = nfc.getFileList();
|
||||||
|
|
||||||
|
// la longitud tiene que ser EXACTAMENTE 1, si es 0 no hay, si es > 1 es ambiguo
|
||||||
|
// y si resulta que dos peers tienen un mismo subhash sin tener el mismo hash?
|
||||||
|
// mando que no se ha podido descargar? comparo contra el hash del primero?
|
||||||
|
FileInfo[] peerFilesFound = FileInfo.lookupHashSubstring(peerFiles, hashSubstring);
|
||||||
|
|
||||||
|
for (FileInfo fi : peerFilesFound) {
|
||||||
|
InetSocketAddress[] peersWithHash = results.getOrDefault(fi.fileHash, null);
|
||||||
|
|
||||||
|
if (peersWithHash == null) {
|
||||||
|
peersWithHash = new InetSocketAddress[1];
|
||||||
|
peersWithHash[0] = addr;
|
||||||
|
} else {
|
||||||
|
peersWithHash = Arrays.copyOf(peersWithHash, peersWithHash.length + 1);
|
||||||
|
peersWithHash[peersWithHash.length - 1] = addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
results.put(fi.fileHash, peersWithHash);
|
||||||
|
}
|
||||||
|
} catch (IOException e) { e.printStackTrace(); }
|
||||||
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user