Wait until it is appropriate to resume writing to the stream.
Example:

writer.write(data)awaitwriter.drain()

This is a flow control method that interacts with the underlying
IO write buffer. When the size of the buffer reaches
the high watermark, drain() blocks until the size of the
buffer is drained down to the low watermark and writing can
be resumed. When there is nothing to wait for, the drain()
returns immediately.

importasyncioasyncdefhandle_echo(reader,writer):data=awaitreader.read(100)message=data.decode()addr=writer.get_extra_info('peername')print(f"Received {message!r} from {addr!r}")print(f"Send: {message!r}")writer.write(data)awaitwriter.drain()print("Close the connection")writer.close()asyncdefmain():server=awaitasyncio.start_server(handle_echo,'127.0.0.1',8888)addr=server.sockets[0].getsockname()print(f'Serving on {addr}')asyncwithserver:awaitserver.serve_forever()asyncio.run(main())

importasyncioimportsocketasyncdefwait_for_data():# Get a reference to the current event loop because# we want to access low-level APIs.loop=asyncio.get_running_loop()# Create a pair of connected sockets.rsock,wsock=socket.socketpair()# Register the open socket to wait for data.reader,writer=awaitasyncio.open_connection(sock=rsock)# Simulate the reception of data from the networkloop.call_soon(wsock.send,'abc'.encode())# Wait for datadata=awaitreader.read(100)# Got data, we are done: close the socketprint("Received:",data.decode())writer.close()# Close the second socketwsock.close()asyncio.run(wait_for_data())