Trio: What about UDP ?

Created on 20 May 2018  路  4Comments  路  Source: python-trio/trio

HI,can anybody give me some code deal with UDP stream ?
I searched the repository,but got nothing.

Most helpful comment

Good question! Trio doesn't currently have any "high level abstraction" for working with UDP, because UDP is pretty low-level :-). But you can use UDP with trio by using the "low level" module trio.socket. There are a lot of examples in the internet showing you how to use UDP in regular python using the socket module. It should be pretty straightforward to convert those to work with trio instead. I'll show you how.

The trio.socket module is a copy of the regular socket module, except that you have to put await in front of I/O operations. (And then, Python's normal rules say that you have to put any await inside an async def; this part is discussed in the trio tutorial.)

For example, here's some regular python code from https://wiki.python.org/moin/UdpCommunication (I added parentheses to the print calls to make it python 3 compatible):

import socket

UDP_IP = "127.0.0.1"
UDP_PORT = 5005
MESSAGE = "Hello, World!"

print("UDP target IP:", UDP_IP)
print("UDP target port:", UDP_PORT)
print("message:", MESSAGE)

sock = socket.socket(socket.AF_INET, # Internet
                     socket.SOCK_DGRAM) # UDP 
sock.sendto(MESSAGE, (UDP_IP, UDP_PORT))

And here's the same code, but adapted for trio:

import trio

UDP_IP = "127.0.0.1"
UDP_PORT = 5005
MESSAGE = "Hello, World!"

async def main():
    print("UDP target IP:", UDP_IP)
    print("UDP target port:", UDP_PORT)
    print("message:", MESSAGE)

    sock = trio.socket.socket(trio.socket.AF_INET, # Internet
                              trio.socket.SOCK_DGRAM) # UDP
    await sock.sendto(MESSAGE, (UDP_IP, UDP_PORT))

trio.run(main)

So the differences are:

  • import trio instead of import socket. (Importing trio automatically imports trio.socket)
  • put the socket code inside an async def, and run it with trio.run
  • replace all references to the socket module with trio.socket
  • add await in front of methods like sock.sendto

And here's the server code from that page adapted to trio as well. If you run this, and then run the first program in a different terminal, you should see that it successfully sends and receives a message. (Unless I messed something up... I'm typing this on my phone so I can't test them myself!)

import trio

UDP_IP = "127.0.0.1"
UDP_PORT = 5005

async def main():
    sock = trio.socket.socket(trio.socket.AF_INET, # Internet
                              trio.socket.SOCK_DGRAM) # UDP
    await sock.bind((UDP_IP, UDP_PORT))
    while True:
        data, addr = await sock.recvfrom(1024) # buffer size is 1024 bytes
        print("received message:", data)
        print("from:", addr)

trio.run(main)

All 4 comments

Good question! Trio doesn't currently have any "high level abstraction" for working with UDP, because UDP is pretty low-level :-). But you can use UDP with trio by using the "low level" module trio.socket. There are a lot of examples in the internet showing you how to use UDP in regular python using the socket module. It should be pretty straightforward to convert those to work with trio instead. I'll show you how.

The trio.socket module is a copy of the regular socket module, except that you have to put await in front of I/O operations. (And then, Python's normal rules say that you have to put any await inside an async def; this part is discussed in the trio tutorial.)

For example, here's some regular python code from https://wiki.python.org/moin/UdpCommunication (I added parentheses to the print calls to make it python 3 compatible):

import socket

UDP_IP = "127.0.0.1"
UDP_PORT = 5005
MESSAGE = "Hello, World!"

print("UDP target IP:", UDP_IP)
print("UDP target port:", UDP_PORT)
print("message:", MESSAGE)

sock = socket.socket(socket.AF_INET, # Internet
                     socket.SOCK_DGRAM) # UDP 
sock.sendto(MESSAGE, (UDP_IP, UDP_PORT))

And here's the same code, but adapted for trio:

import trio

UDP_IP = "127.0.0.1"
UDP_PORT = 5005
MESSAGE = "Hello, World!"

async def main():
    print("UDP target IP:", UDP_IP)
    print("UDP target port:", UDP_PORT)
    print("message:", MESSAGE)

    sock = trio.socket.socket(trio.socket.AF_INET, # Internet
                              trio.socket.SOCK_DGRAM) # UDP
    await sock.sendto(MESSAGE, (UDP_IP, UDP_PORT))

trio.run(main)

So the differences are:

  • import trio instead of import socket. (Importing trio automatically imports trio.socket)
  • put the socket code inside an async def, and run it with trio.run
  • replace all references to the socket module with trio.socket
  • add await in front of methods like sock.sendto

And here's the server code from that page adapted to trio as well. If you run this, and then run the first program in a different terminal, you should see that it successfully sends and receives a message. (Unless I messed something up... I'm typing this on my phone so I can't test them myself!)

import trio

UDP_IP = "127.0.0.1"
UDP_PORT = 5005

async def main():
    sock = trio.socket.socket(trio.socket.AF_INET, # Internet
                              trio.socket.SOCK_DGRAM) # UDP
    await sock.bind((UDP_IP, UDP_PORT))
    while True:
        data, addr = await sock.recvfrom(1024) # buffer size is 1024 bytes
        print("received message:", data)
        print("from:", addr)

trio.run(main)

Here's a more detailed example of using UDP with Trio: https://github.com/python-trio/trio/blob/master/notes-to-self/ntp-example.py

Thanks very much.

Glad that helped! If you have more questions feel free to ask here or in chat. Or even if you don't have a question, we'd love to hear more about what you're working on :-)

Was this page helpful?
0 / 5 - 0 ratings