¿Qué son los sockets?
Los
protocolos TCP y UDP utilizan la abstracción de sockets para proporcionar los puntos
extremos de la comunicación entre aplicaciones o procesos.
Para
los procesos receptores de mensajes, su conector debe tener asociado dos
campos:
- La dirección IP del host en el que la aplicación está corriendo.
- El puerto local a través del cual la aplicación se comunica y que identifica el proceso.
Funcionamient en general de un socket
El
programa cliente conoce el nombre de la máquina en la que se ejecuta el
servidor y el número de puerto por el que escucha las peticiones. Para realizar
una solicitud de conexión, el cliente realiza la petición a la máquina a través
del puerto.
Si todo
va bien, el servidor acepta la conexión. Una vez aceptada, el servidor obtiene
un nuevo socket sobre un puerto diferente. Esto se debe a que por un lado debe
seguir atendiendo las peticiones de conexión mediante el socket original y por
otro debe antender las necesidades del cliente que se conectó.
En el
lado del cliente, si se acepta la conexión, se crea un socket y el cliente
puede utilizarlo para comunicarse con el servidor. Este socket utiliza un
número de puerto diferente al usado para conectarse al servidor. El cliente y
el servidor pueden ahora comunicarse escribiendo y leyendo por sus respectivos
sockets.
Clase ServerSocket
Se
utiliza para implementar el extremo de la conexión que corresponde al servidor,
donde se crea un conector en el puerto del servidor que escucha las peticiones
de conexión de los clientes.
Constructores
Algunos métodos importantes
Ejemplo
Archivo
SocketServidor.java
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class SocketServidor {
public static void main(String[] args) throws IOException {
int Puerto = 6000;// Puerto
ServerSocket Servidor=null;
Servidor = new ServerSocket(Puerto);
System.out.println("Escuchando
en " + Servidor.getLocalPort());
Socket clientel = Servidor.accept();//esperando
a un cliente
//realizar
acciones con clientel
Socket cliente2 = Servidor.accept();//esperando
a otro cliente
//realizar
acciones con cliente2
Servidor.close(); //cierro
socket servidor
}//fin de
main
}//fin de SocketServidor
Clase Socket
Implementa
un extremo de la conexión TCP.
Constructores
Algunos métodos importantes
Ejemplo
Archivo SocketCliente.java
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
public class SocketCliente {
public static void main(String[] args) throws IOException {
String Host = "localhost";
int Puerto = 6000;//puerto
remoto
// ABRIR
SOCKET
Socket Cliente = new Socket(Host, Puerto);//conecta
InetAddress i= Cliente.getInetAddress
();
System.out.println("Puerto
local: "+ Cliente.getLocalPort());
System.out.println("Puerto
Remoto: "+ Cliente.getPort());
System.out.println("Host
Remoto: "+ i.getHostName().toString());
System.out.println("IP Host
Remoto: "+ i.getHostAddress().toString());
Cliente.close();// Cierra
el socket
}//fin de
main
}//fin de SocketCliente
Gestión de Sockets TCP
El programa servidor crea un socket de servidor definiendo un puerto, mediante el método ServerSocket(port), y espera mediante el método accept() a que el cliente solicite la conexión.
Cuando el cliente solicita una conexión, el servidor abrirá la conexión al socket con el método accept().
El cliente establece una conexión con la máquina host a través del uerto especificado mediante el método Socket(host, port).
El cliente y el servidor se comunican con manejadores InputStream y OutputStream. El cliente escribe los mensajes en el OutputStream asociado al socket y el servidor leerá los mensajes del cliente de InputStream. Igualmente el servidor escribirá los mensajes al OutputStream y el cliente los leerá del InputStream.
Hay puertos TCP de 0 a 65535.
Los puertos en el rango de 0 a 1023 están reservados para servicios privilegiados.
De 1024 a 49151 están reservados para aplicaciones concretas (por ejemplo el 3306 lo usa MySQL, el 1521 Oracle).
De 49152 a 65535 no están reservados para ninguna aplicación concreta.
Ejemplo.
El programa servidor (Ejemplo1Servidor) recibe un mensaje de un cliente y lo muestra por pantalla; después envía un mensaje al cliente. Se han eliminado los bloques try-catch para que el código resulte más legible.
Archivo Ejemplo1Servidor.java
import java.io.*;
import java.net.*;
public class Ejemplo1Servidor {
public static void main(String[] arg) throws IOException {
int numeroPuerto = 6000;// Puerto
ServerSocket servidor = new ServerSocket(numeroPuerto);
Socket clienteConectado = null;
System.out.println("Esperando al cliente.....");
clienteConectado = servidor.accept();
// CREO FLUJO DE ENTRADA DEL CLIENTE
InputStream entrada = null;
entrada = clienteConectado.getInputStream();
DataInputStream flujoEntrada = new DataInputStream(entrada);
// EL CLIENTE ME ENVIA UN MENSAJE
System.out.println("Recibiendo del CLIENTE: \n\t" + flujoEntrada.readUTF());
// CREO FLUJO DE SALIDA AL CLIENTE
OutputStream salida = null;
salida = clienteConectado.getOutputStream();
DataOutputStream flujoSalida = new DataOutputStream(salida);
// ENVIO UN SALUDO AL CLIENTE
flujoSalida.writeUTF("Saludos al cliente del servidor");
// CERRAR STREAMS Y SOCKETS
entrada.close();
flujoEntrada.close();
salida.close();
flujoSalida.close();
clienteConectado.close();
servidor.close();
}// main
}// fin de Ejemplo1Servidor
El programa cliente (Ejemplo1Cliente) envía un mensaje al servidor y después recibe un mensaje del servidor visualizándolo en pantalla, se ha simplificado la obtención de los flujos de entrada y salida.
Archivo Ejemplo1Cliente.java
import java.io.*;
import java.net.*;
public class Ejemplo1Cliente {
public static void main(String[] args) throws Exception {
String Host = "localhost";
int Puerto = 6000;//puerto remoto
System.out.println("PROGRAMA CLIENTE INICIADO....");
Socket Cliente = new Socket(Host, Puerto);
// CREO FLUJO DE SALIDA AL SERVIDOR
DataOutputStream flujoSalida = new DataOutputStream(Cliente.getOutputStream());
// ENVIO UN SALUDO AL SERVIDOR
flujoSalida.writeUTF("SaludOS al SERVIDOR DESDE EL CLIENTE");
// CREO FLUJO DE ENTRADA AL SERVIDOR
DataInputStream flujoEntrada = new DataInputStream(Cliente.getInputStream());
// EL SERVIDOR ME ENVIA UN MENSAJE
System.out.println("Recibiendo del SERVIDOR: \n\t" + flujoEntrada.readUTF());
// CERRAR STREAMS Y SOCKETS
flujoEntrada.close();
flujoSalida.close();
Cliente.close();
}// fin de main
}// Fin de Ejemplo1Cliente
De mucho interés, agradezco vuestra valiosa aportación a la comunidad en esta jornada.
ResponderEliminar