Socket TCP en Java: implementación de Cliente y Servidor con intercambio de contraseñas
Enviado por Chuletator online y clasificado en Informática y Telecomunicaciones
Escrito el en
español con un tamaño de 5,19 KB
Socket TCP en Java: cliente y servidor con intercambio de contraseñas
Se presenta una implementación sencilla en Java que muestra un cliente y un servidor que intercambian un saludo, el nombre del usuario y una contraseña aleatoria de 4 dígitos. A continuación se corrige y organiza el código y los comentarios del ejemplo original.
Cliente
Descripción: el cliente crea un socket, se conecta al servidor, recibe el saludo, envía el nombre y recibe la contraseña asignada.
public class Cliente {
public static void main(String[] args) {
try {
System.out.println("Creando socket cliente");
Socket clientSocket = new Socket();
System.out.println("Estableciendo conexión");
InetSocketAddress addr = new InetSocketAddress(HOST, PUERTO); // Dirección IP y puerto
clientSocket.connect(addr); // Paso la petición al socket servidor
InputStream is = clientSocket.getInputStream();
OutputStream os = clientSocket.getOutputStream();
// Recogemos saludo del servidor:
byte[] saludo = new byte[100]; // 100 bytes para el saludo
is.read(saludo);
System.out.println(new String(saludo));
Scanner scanner = new Scanner(System.in);
String nombre = scanner.next();
os.write(nombre.getBytes());
// Recogemos la contraseña (pss) de 4 bytes
byte[] pss = new byte[4]; // 4 bytes de pss
is.read(pss);
System.out.println("Contraseña asignada: " + new String(pss));
scanner.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
Servidor
Descripción: el servidor crea un ServerSocket, realiza el bind a la dirección y puerto, y acepta hasta 5 conexiones. Para cada conexión saluda al cliente, recibe su nombre, le asigna una contraseña aleatoria de 4 dígitos y almacena la información de usuario.
public class Servidor {
private static ArrayList usuarios = new ArrayList();
public static void main(String[] args) {
try {
Scanner s = new Scanner(System.in);
System.out.println("Creación del socket servidor");
// Usamos un ServerSocket para establecer la conexión
ServerSocket serverSocket = new ServerSocket();
System.out.println("Realización del bind");
InetSocketAddress iSA = new InetSocketAddress(HOST, PUERTO); // Dirección IP y puerto
serverSocket.bind(iSA); // Habilitamos IP y puerto para que un socket cliente pueda hacer peticiones
for (int i = 1; i <= 5; i++) {
System.out.println("Espera a que llegue una petición de socket");
// Queda a la espera de una petición por parte de un socket cliente
Socket socket = serverSocket.accept(); // Momento en el que se crea el socket (se comunica) -> se desbloquea
// Al aceptar la petición de un socket cliente empezamos a trabajar con ese socket
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
// Saludamos al cliente y pedimos nombre
String saludoACliente = "Hola cliente " + i + "\nIntroduce tu nombre: ";
os.write(saludoACliente.getBytes());
// Recogemos el nombre del usuario que ha introducido el cliente:
byte[] nombre = new byte[100];
is.read(nombre);
String nombreUsuario = new String(nombre);
// Asignamos contraseña aleatoria de 4 dígitos:
Random r = new Random();
String contrasenia = String.valueOf(r.nextInt(9000) + 1000);
os.write(contrasenia.getBytes());
System.out.println("Contraseña " + contrasenia + " asignada al cliente " + nombreUsuario);
usuarios.add(new Usuario(nombreUsuario, contrasenia));
}
System.out.println("\nUsuarios conectados:");
for (Usuario usu : usuarios) {
System.out.println(usu);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Notas y recomendaciones
- Reemplazar HOST y PUERTO por los valores adecuados (por ejemplo, "localhost" y 12345) o definir constantes apropiadas.
- Al recibir cadenas con buffers de tamaño fijo (por ejemplo,
byte[] nombre = new byte[100]), conviene aplicarnew String(bytes).trim()para eliminar caracteres nulos o espacios sobrantes. - Añadir los imports necesarios si se compila por separado:
import java.io.*;,import java.net.*;,import java.util.*;. - Considerar cerrar sockets y streams explícitamente en bloques
finallyo usando try-with-resources para evitar fugas de recursos. - Evitar usar buffers fijos sin protocolo explícito; para aplicaciones reales, usar delimitadores o longitudes prefijadas y manejar correctamente la codificación (por ejemplo, UTF-8).