It is possible to do the same as :doc:`the TCP server tutorial <./echo_client_server_tcp>` with UDP sockets.
Table of Contents
You will need a :term:`protocol object`, as for the :ref:`echo client/server over TCP <echo-client-server-tcp-protocol>`.
For the tutorial, :class:`.JSONSerializer` will also be used.
For communication via UDP, a :class:`.DatagramProtocol` object must be created this time.
.. literalinclude:: ../_include/examples/tutorials/echo_client_server_udp/json_protocol.py :linenos: :caption: json_protocol.py :emphasize-lines: 5,14
First, you must create a request handler class by subclassing the :class:`.AsyncDatagramRequestHandler` class and overriding its :meth:`~.AsyncDatagramRequestHandler.handle` method; this method will process incoming requests.
.. literalinclude:: ../_include/examples/tutorials/echo_client_server_udp/echo_request_handler.py :linenos: :caption: echo_request_handler.py :emphasize-lines: 13,16,20
Note
There is no connection pipe with UDP, so there is no aclose()
method.
But the client object still has an is_closing()
that returns :data:`True` when the server itself closes.
Second, you must instantiate the UDP server class, passing it the server's address, the :term:`protocol object` instance, and the request handler instance.
.. tabs:: .. group-tab:: Synchronous .. literalinclude:: ../_include/examples/tutorials/echo_client_server_udp/server.py :linenos: :caption: server.py .. group-tab:: Asynchronous .. literalinclude:: ../_include/examples/tutorials/echo_client_server_udp/async_server.py :linenos: :caption: server.py
This is the client side:
.. tabs:: .. group-tab:: Synchronous .. literalinclude:: ../_include/examples/tutorials/echo_client_server_udp/client.py :linenos: :caption: client.py .. group-tab:: Asynchronous .. literalinclude:: ../_include/examples/tutorials/echo_client_server_udp/async_client.py :linenos: :caption: client.py
Note
This is a "spoofed" connection. In fact, the socket is saving the address and will only send data to that endpoint.
The output of the example should look something like this:
Server:
.. tabs:: .. group-tab:: IPv4 connection .. code-block:: console (.venv) $ python server.py 127.0.0.1 sent {'command-line arguments': ['Hello', 'world!']} 127.0.0.1 sent {'command-line arguments': ['Python', 'is', 'nice']} .. group-tab:: IPv6 connection .. code-block:: console (.venv) $ python server.py ::1 sent {'command-line arguments': ['Hello', 'world!']} ::1 sent {'command-line arguments': ['Python', 'is', 'nice']}
Client:
(.venv) $ python client.py Hello world!
Sent: {'command-line arguments': ['Hello', 'world!']}
Received: {'command-line arguments': ['Hello', 'world!']}
(.venv) $ python client.py Python is nice
Sent: {'command-line arguments': ['Python', 'is', 'nice']}
Received: {'command-line arguments': ['Python', 'is', 'nice']}