简体   繁体   中英

Force a non-blocking UDP socket to raise BlockingIOError on sendto

I believe that a non-blocking UDP socket can raise a BlockingIOError on sendto. I would like to force this situation to test how my program behaves in this case.

sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
sock.setblocking(False)
sock.bind(('', 7777))
...
# Even if repeating in a loop, doesn't seem to raise a BlockingIOError
sock.sendto(b'abcde', ('1.2.3.4', 61908))

I have tried setting the outgoing buffer small by

buffer_size = 5
sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, buffer_size)

But it either seems to have no impact, or results in OSError: [Errno 40] Message too long if the buffer is smaller than the data.

Is my belief wrong: can it never raise a BlockingIOError? Or if it can, how can I force it?

My aim here is to have an integration-style test: I want to actually have a real socket and make actual network calls. Mocking the socket for a unit-style test in this case would not be ideal.

The socket will only be used from a single-threaded Python asyncio program.

From TCP/IP Sockets in C: Practical Guide for Programmers, Michael J. Donahoo, Kenneth L. Calvert

For UDP sockets, there are no send buffers, so send() and sendto() never return EWOULDBLOCK

And from https://linux.die.net/man/2/sendto there is a hint as to why...

Packets are just silently dropped when a device queue overflows.

So in Python terms, BlockingIOError cannot be raised, at least on Linux.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM