- Conexión confiable
- Clase genérica socket
- socket():
- socket.AF_INET: Este es el dominio del conector, en este caso, un conector IPv4.
- socket.SOCK_STREAM: Este es el tipo del conector, que depende del parámetro anterior (no todos los dominios soportan los mismos tipos). En este caso, SOCK_STREAM se refiere a un socket de stream (flujo) TCP.
- bind(): Sólo admite un parámetro por lo que mediante una lista enviamos host+puerto. Como host podremos enviar tanto la IP como un nombre de equipo que pueda ser resuelto por la red o por DNS.
- listen(): Con un “1” ponemos el servidor en modo escucha, donde 1 es la longitud de la cola de espera, el número de conexiones entrantes completadas por la pila TCP/IP pero no han sido aceptadas por la aplicación. NO CONFUNDIR CON EL NÚMERO DE CONEXIONES CONCURRENTES. Es el número máximo de clientes que pueden posicionarse en la cola de espera para ser atendidos. En el ejemplo de abajo podría ser 0 o 1 como hemos puesto y tampoco pasaría nada si pusiéramos 100 ya que el servidor no está programado con threads, si utilizáramos threads para atender a múltiples clientes sí sería relevante dicho número.
- accept(): Se trata de una instrucción bloqueante, es decir se queda a la espera de algo, en este caso que entre una petición de comunicación a través del socket que entrará a través del sistema operativo cuando ocurra dicho evento. Una vez haya entrado una petición podremos capturar los datos genéricos del socket origen. Es decir aparece la dirección del cliente conectado, dato crucial si lo que queremos hacer es devolverle algún tipo de dato, esa dirección nos viene con dos parámetros la IP y el puerto (addr[0] addr[1] respectivamente).
- close(): cierre de un cliente o una conexión. En el ejemplo primero cerramos la conexión del cliente (conn.close() ) y posteriormente cerramos el socket del servidor (s.close()) esta última instrucción envía una señal a todos los clientes conectados para que cierren la conexión y libera todos los recursos asociados al socket del servidor.
- s.accept(): Esta es una función que acepta una conexión. El socket debe estar vinculado a una dirección y escuchando conexiones.
- conn, addr: La función s.accept() devuelve un par (conn, address), donde conn es un nuevo objeto de socket que se puede usar para enviar y recibir datos en la conexión, y addr es la dirección vinculada al socket en el otro extremo de la conexión.
Por lo tanto, conn, addr = s.accept()
está aceptando una conexión entrante y devolviendo un nuevo objeto de socket y la dirección del cliente. Esto es típicamente usado en servidores de sockets para manejar múltiples conexiones de clientes.
import socket
HOST = '127.0.0.1' # direccion de loopback standard para localhost
PORT = 2000 # Puerto de escucha
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
#escuchamos por el puerto
s.bind((HOST, PORT))
#aceptamos conexiones
s.listen(1)
#aceptamos conexiones entrantes con el método accept.
#devuelve un objeto socket y una tupla con la dirección del cliente
conn, addr = s.accept() #función bloqueante
print (f"Conexión exitosa con el cliente. IP ({addr[0]}) Puerto ({addr[1]})")
#cerramos la conexión con ese cliente
conn.close()
except socket.error as exc:
print ("Excepción de socket: %s" % exc)
finally:
#cerramos la escucha general de nuestro servidor
s.close()
telnet 127.0.0.1 2000
Conexión exitosa con el cliente. IP (127.0.0.1) Puerto (57895)
Conexión exitosa con el cliente. IP (127.0.0.1) Puerto (59620)
El puerto es generado por el sistema operativo de manera aleatoria en cada ejecución.
Hay dos direcciones especiales:
”
: cadena vacía que permite enlazar con todas las tarjetas de red
<broadcast>
: que se utiliza para usar la dirección de multidifusión.