Рубрики
Без рубрики

Клиент и сервер дейтаграмм пользователя

Автор оригинала: Doug Hellmann.

Протокол пользовательских дейтаграмм (UDP) работает иначе, чем TCP/IP. Если TCP – это ориентированный на поток протокол, гарантирующий, что все данные передаются в правильном порядке, UDP – это протокол ориентированный на сообщения . UDP не требует длительного соединения, поэтому настроить сокет UDP немного проще. С другой стороны, сообщения UDP должны умещаться в одной дейтаграмме (для IPv4 это означает, что они могут содержать только 65 507 байт, поскольку пакет из 65 535 байт также включает информацию заголовка), и доставка не гарантируется, как в случае с TCP.

Эхо-сервер

Поскольку соединение само по себе отсутствует, серверу не нужно прослушивать и принимать соединения. Ему нужно только использовать bind () , чтобы связать свой сокет с портом, а затем ждать отдельных сообщений.

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))

Сообщения читаются из сокета с помощью recvfrom () , который возвращает данные, а также адрес клиента, с которого они были отправлены.

Эхо-клиент

Эхо-клиент UDP похож на сервер, но не использует bind () для присоединения своего сокета к адресу. Он использует sendto () для доставки своего сообщения непосредственно на сервер и recvfrom () для получения ответа.

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()

Клиент и сервер вместе

Запуск сервера производит:

$ 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

Вывод клиента:

$ 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