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 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; } }