No, you cannot expect socket.sendto
to be non-blocking.
Instead, use DatagramTransport.sendto:
Send the data bytes to the remote peer given by addr (a transport-> dependent target address). If addr is None, the data is sent to the target address given on transport creation.
This method does not block; it buffers the data and arranges for it to be sent out asynchronously.
The datagram transport is returned by the loop.create_datagram_endpoint coroutine:
transport, protocol = await loop.create_datagram_endpoint(factory, sock=sock)
EDIT - About your comment:
Is socket.sendto() equivalent to transport.sendto()?
No it's not, transport.sendto
uses loop.add_writer
to make the operation non-blocking. See the implementation.
I do not want to use this method because of it's implementation which enforce me to receive data through protocol with callback style.
The lower level of asyncio is based on callbacks and asyncio doesn't provide coroutine-based objects for UDP. However, I wrote a module that provides high-level UDP endpoints for asyncio.
Usage:
async def main():
local = await open_local_endpoint()
remote = await open_remote_endpoint(*local.address)
remote.write(b'Hey Hey, My My')
data, addr = await local.read()
message = "Got {data!r} from {addr[0]} port {addr[1]}"
print(message.format(data=data.decode(), addr=addr))
Output:
Got 'Hey Hey, My My' from 127.0.0.1 port 45551