mirror of
https://github.com/binlaab/nanofiles.git
synced 2026-07-01 18:26:30 +02:00
quemen redes
This commit is contained in:
@@ -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,20 +20,25 @@ 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());
|
||||
|
||||
|
||||
|
||||
@@ -39,9 +46,33 @@ public class NFConnector {
|
||||
|
||||
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
|
||||
@@ -87,6 +119,26 @@ public class NFServer implements Runnable {
|
||||
* hilo es el que se encarga de atender al cliente conectado, no podremos tener
|
||||
* 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user