Cliente y servidor de datagrama de usuario

El protocolo de datagramas de usuario (UDP) funciona de manera diferente a TCP/IP. Mientras TCP es un protocolo orientado al flujo, que garantiza que todos los datos sean transmitido en el orden correcto, UDP es un protocolo orientado a mensajes. UDP no requiere una conexión de larga duración, por lo que configurar un conector UDP es un poco más sencillo. Por otro lado, los mensajes UDP deben caber dentro de un solo datagrama (para IPv4, eso significa que solo pueden contener 65,507 bytes porque el paquete de 65,535 bytes también incluye encabezado de información) y la entrega no está garantizada como lo es con TCP.

Servidor de eco

Dado que no hay conexión, per se, el servidor no necesita escuchar y acepta conexiones. Solo necesita usar bind() para asociar su conector con un puerto, y luego esperar mensajes.

socket_echo_server_dgram.py
import socket
import sys

# Create a UDP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# Bind the socket to the port
server_address = ('localhost', 10000)
print('starting up on {} port {}'.format(*server_address))
sock.bind(server_address)

while True:
    print('\nwaiting to receive message')
    data, address = sock.recvfrom(4096)

    print('received {} bytes from {}'.format(
        len(data), address))
    print(data)

    if data:
        sent = sock.sendto(data, address)
        print('sent {} bytes back to {}'.format(
            sent, address))

Los mensajes se leen desde el conector usando recvfrom(), que devuelve los datos, así como la dirección del cliente desde dónde fue enviado.

Cliente de eco

El cliente de eco UDP es similar al servidor, pero no usa bind() para adjuntar su conector a una dirección. Usa sendto() para entregar su mensaje directamente al servidor, y recvfrom() para recibir la respuesta.

socket_echo_client_dgram.py
import socket
import sys

# Create a UDP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

server_address = ('localhost', 10000)
message = b'This is the message.  It will be repeated.'

try:

    # Send data
    print('sending {!r}'.format(message))
    sent = sock.sendto(message, server_address)

    # Receive response
    print('waiting to receive')
    data, server = sock.recvfrom(4096)
    print('received {!r}'.format(data))

finally:
    print('closing socket')
    sock.close()

Cliente y servidor juntos

Ejecutar el servidor produce:

$ python3 socket_echo_server_dgram.py
starting up on localhost port 10000

waiting to receive message
received 42 bytes from ('127.0.0.1', 57870)
b'This is the message.  It will be repeated.'
sent 42 bytes back to ('127.0.0.1', 57870)

waiting to receive message

La salida del cliente es:

$ python3 socket_echo_client_dgram.py
sending b'This is the message.  It will be repeated.'
waiting to receive
received b'This is the message.  It will be repeated.'
closing socket