Автор оригинала: 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