Un socket es un concepto de programación implementado dentro de un sistema Operativo (SO), generalmente soportado por un lenguaje de programación de alto nivel (C#, Java, Pyton etc.),
que permite la comunicación entre diferentes procesos. Entendemos por comunicación entre procesos a la tarea de intercambiar información entre diferentes aplicaciones ejecutándose dentro de una misma computadora o en diferentes computadoras.
Un socket emplea el protocolo TCP (Protocolo de control de transmisión) para realizar la conexión y comunicación entre sus terminales; Una terminal es el punto final en la comunicación donde se encuentra ubicado el proceso a conectar.
Los sockets se diseñan bajo una arquitectura conocida como Cliente/Servidor.
¿Cuál es la importancia de los sockets?
En la actualidad muchas aplicaciones están implementadas usando sockets de forma interna. Por ejemplo: los gestores de bases de datos relacionales, chats, herramientas para el control de versiones, servicios en la nube, e incluso las páginas que solicitamos en el internet se envían y reciben en los browser a través de sockets.
En programación los sockets tienen mucha importancia debido a su uso extendido. A través de ellos y en conjunto con un patrón de diseño podemos implementar un servicio web robusto y extensible, como lo es el caso de un Bróker.
Para simplificar esta lectura haremos referencia a un proceso como una aplicación o programa que se ejecutara en una computadora.
Diferencias entre Sockets y Tuberías
Una tubería es básicamente un espacio de memoria compartida entre procesos a los cuales se accede de manera ordenada dentro de una misma computadora. Los sockets a diferencia de las tuberías (Pipes) transmiten información sin importar si los procesos en los cuales se alojan se encuentran o no dentro de la misma computadora.
Programación de los sockets
Un socket se conecta configurando lo siguiente:
- Host: es una dirección única dentro de la red donde se encuentra el proceso a conectar.
- Numero de puerto: Número que identifica a la aplicación dentro de una computadora conectada a la red. Dos sockets no pueden enviar o recibir información por el mismo puerto al mismo tiempo dentro de un mismo SO, sin que uno sea Cliente y el otro el Servidor.
- Flujo de entrada y salida: mediante estos flujos se puede enviar y recibir información como una secuencia de bytes o caracteres una vez que el socket esté conectado y haya sido abierto.
- Bloqueante/No Bloqueante: Los sockets por defecto son bloqueantes, es decir bloquean el proceso donde se encuentran alojados hasta que la información sea enviada o recibida por completo. En muchas ocasiones es posible configurar esta característica, sin embargo esto no garantiza que la información sea enviada o recibida totalmente. Por ejemplo si un socket es configurado para no ser bloqueante e intenta enviar muchos bytes de información. El socket escribirá tantos bytes como le sea posible sin esperar a que toda la información sea transmitida en el flujo de salida y retornara inmediatamente el control al proceso que lo invoco.
Proceso para la comunicación entre sockets
Servidor
Un socket que funge como servidor operara de la siguiente manera:
- El proceso crea un socket servidor para escuchar en un puerto específico y espera conexiones entrantes de algún socket cliente alojado en algún otro proceso.
- Una vez que una conexión haya sido establecida se creara un socket cliente que entablara la comunicación con el socket que solicito la conexión en el otro proceso.
- Cuando la comunicación con el socket cliente es finalizada. la conexión es cerrada.
- El socket servidor continúa esperando conexiones de otro socket cliente.
Generalmente la espera se realiza dentro de un ciclo infinito.
Cliente
Un socket cliente funcionara de la siguiente forma:
- El proceso crea un socket cliente configurando la dirección IP y el puerto donde el socket server espera por conexiones.
- El socket cliente entabla una comunicación con el socket servidor.
- Una vez que la comunicación ha finalizado el socket es cerrado.
Ejemplo de programación
Como un ejemplo para esta lectura crearemos 2 sockets. El primero fungirá como servidor siguiendo los pasos descritos arriba y el segundo fungirá como cliente. El lenguaje de programación elegido será C#. Otros 2 sockets serán programados en JAVA para ilustrar la programación de los sockets como concepto.
Los detalles de la implementación de los socket los puede revisar en los códigos adjuntados a esta lectura.
Descripción del código del socket servidor:
A continuación describimos los pasos realizados en el código para la comunicación con un socket desde el servidor.
Línea 61: Se crea un objeto del tipo TcpListener el cual acepta conexiones para entablar comunicación con algún otro socket cliente. Este objeto funge como un socket servidor.
Linea 62: Iniciamos el servidor mediante el método Start() para que espere por conexiones entrantes.
Línea 68: Se crea un ciclo infinito para que el servidor pueda esperar por conexiones entrantes.
Línea 71: El servidor podrá recibir conexiones de sockets ubicados en otro proceso mediante el método AcceptSocket().
Línea 72: Recibe algún mensaje del socket con el cual se entablo la comunicación. Observe que por cada conexión entrante se creara un socket para la comunicación.
Línea 73: El mensaje recibido es enviado de vuelta al socket que inicio la conexión convirtiendo el mensaje recibido en mayúsculas.
Línea: 74: Se cierra finalmente la conexión con el socket cliente.
Descripción del código del socket cliente:
A continuación describimos los pasos realizados en el código para la comunicación con el socket servidor desde el cliente.
Línea 53: Se crea un socket cliente y se abre la conexión para entablar la conexión con el socket servidor.
Línea 54: Se envía el mensaje “Hello World” al servidor mediante el socket creado.
Línea 55: La respuesta recibida desde el servidor es recibida y almacenada en una cadena de caracteres. En este caso la cadena contendrá la misma frase enviada al servidor solo que en mayúsculas.
Línea 56: Cierra finalmente la conexión con el servidor.
El resultado de ejecutar ambos programas seria el siguiente (recuerde ejecutar primero el servidor y después el cliente):
En este link puedes descargar los ejemplos de programación de sockets en lenguaje C# y Java: