mirror of
https://github.com/binlaab/nanofiles.git
synced 2026-07-01 15:07:21 +02:00
146 lines
5.1 KiB
Java
146 lines
5.1 KiB
Java
package es.um.redes.nanoFiles.tcp.client;
|
|
|
|
import java.io.DataInputStream;
|
|
import java.io.DataOutputStream;
|
|
import java.io.IOException;
|
|
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 java.util.LinkedList;
|
|
|
|
import es.um.redes.nanoFiles.tcp.message.PeerMessage;
|
|
import es.um.redes.nanoFiles.tcp.message.PeerMessageOps;
|
|
import es.um.redes.nanoFiles.util.FileInfo;
|
|
|
|
//Esta clase proporciona la funcionalidad necesaria para intercambiar mensajes entre el cliente y el servidor
|
|
public class NFConnector {
|
|
private Socket socket;
|
|
private InetSocketAddress serverAddr;
|
|
|
|
public static final int CHUNK_SIZE = 64 * 1024; // 64 kB máx
|
|
|
|
private DataInputStream dis;
|
|
private DataOutputStream dos;
|
|
|
|
public NFConnector(InetSocketAddress fserverAddr) throws UnknownHostException, IOException {
|
|
serverAddr = fserverAddr;
|
|
/*
|
|
* 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.
|
|
*/
|
|
/*
|
|
* 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.
|
|
*/
|
|
try {
|
|
|
|
socket = new Socket(fserverAddr.getAddress(), fserverAddr.getPort());
|
|
} catch (Exception e) { e.printStackTrace(); }
|
|
dis = new DataInputStream(socket.getInputStream());
|
|
dos = new DataOutputStream(socket.getOutputStream());
|
|
}
|
|
|
|
|
|
public void close() {
|
|
try {
|
|
socket.close();
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
public void test() {
|
|
/*
|
|
* 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((byte) 1);
|
|
msgOut.writeMessageToOutputStream(dos);
|
|
System.out.println("sent " + PeerMessageOps.opcodeToOperation(msgOut.getOpcode()));
|
|
PeerMessage msgIn = PeerMessage.readMessageFromInputStream(dis);
|
|
System.out.println("received " + msgIn.getOpcode() + " " + 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(); }
|
|
}
|
|
|
|
|
|
public FileInfo[] getFileList() {
|
|
try {
|
|
LinkedList<FileInfo> filelist = new LinkedList<>();
|
|
PeerMessage msgOut = new PeerMessage(PeerMessageOps.OPCODE_REQUEST_PEER_FILES);
|
|
msgOut.writeMessageToOutputStream(dos);
|
|
System.out.println("gfl enviado");
|
|
PeerMessage msgIn = PeerMessage.readMessageFromInputStream(dis);
|
|
System.out.println("gfl leido");
|
|
if (msgIn.getOpcode() == PeerMessageOps.OPCODE_PEER_FILE) {
|
|
boolean last = false;
|
|
while (!last) {
|
|
long size = msgIn.getFileSize();
|
|
String hash = msgIn.getFileHash();
|
|
String name = msgIn.getFilenameVal();
|
|
FileInfo file = new FileInfo(hash, name, size, null);
|
|
filelist.add(file);
|
|
last = msgIn.getLast();
|
|
System.out.println("Tenemos otro archivo, last = " + last);
|
|
if (!last) msgIn = PeerMessage.readMessageFromInputStream(dis); // tengo que ver si puedo hacerlo diferente
|
|
}
|
|
} else { return null; }
|
|
System.out.println("Nos vamos de gfl");
|
|
return filelist.toArray(new FileInfo[0]);
|
|
} catch (IOException e) { e.printStackTrace(); return null; }
|
|
}
|
|
|
|
public boolean downloadChunk(String hash, int chunkNum, RandomAccessFile raf) {
|
|
boolean success = false;
|
|
try {
|
|
PeerMessage msgOut = new PeerMessage(PeerMessageOps.OPCODE_REQUEST_PEER_DL);
|
|
msgOut.setFileHash(hash);
|
|
msgOut.setChunkNum(chunkNum);
|
|
msgOut.writeMessageToOutputStream(dos);
|
|
|
|
PeerMessage msgIn = PeerMessage.readMessageFromInputStream(dis);
|
|
|
|
if (msgIn.getOpcode() == PeerMessageOps.OPCODE_PEER_DL) {
|
|
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(); }
|
|
|
|
return success;
|
|
}
|
|
|
|
public InetSocketAddress getServerAddr() {
|
|
return serverAddr;
|
|
}
|
|
|
|
}
|