Нет, вы не можете ожидать, что socket.sendto
будет неблокирующим.
Вместо этого используйте DatagramTransport.sendto:
Отправить байты данных удаленного узла, заданного адром (а транспортно> зависит от целевого адреса). Если addr равно None, данные отправляются на целевой адрес, указанный при создании транспорта.
Этот метод не блокирует; выполняет буферизацию данных и организует их отправку асинхронно.
Датаграмма транспорт возвращается в loop.create_datagram_endpoint сопрограмме:
transport, protocol = await loop.create_datagram_endpoint(factory, sock=sock)
EDIT - О Вашем комментарии:
Is socket.sendto() эквивалентен transport.sendto ()?
Нет, это не так, transport.sendto
использует loop.add_writer
, чтобы сделать операцию неблокирующей. См. implementation.
Я не хочу использовать этот метод из-за его реализации, который принуждает меня принимать данные через протокол с обратным вызовом.
Более низкий уровень asyncio основан на обратных вызовах, и asyncio не предоставляет объекты на основе coroutine для UDP. Тем не менее, я написал module that provides high-level UDP endpoints for asyncio.
Использование:
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))
Выход:
Got 'Hey Hey, My My' from 127.0.0.1 port 45551
[2432814] (http://stackoverflow.com/questions/2432814/python-blocking-sockets-send-returns-immediately) дублировать? – ldavid
извините за то, что упустил этот пост с 'search Q & A'. Я искал такие ключевые слова, как «is sendto non-blocking», «is sendto safe to use in asyncio loop» .. и т. Д. – SpringMaple