讓socket可以用async的方式接收資料
本篇所參考的相關文件:
asyncio
利用 coroutine 機制完成的非同步 I/O 函式庫,它讓以前常常要使用 callback 運行程式的做法變成比較直觀的 async/await 寫法。
asyncio/Event Loop
所有 asyncio 應用程式的核心,它控管所有使用到的 asyncio 事件。
asyncio/Futures
被包裝成 async樣子的 callback 程式段落。
asyncio/Exceptions
定義 Futures 在執行時的異常,有 CancelledError, InvalidStateError, TimeoutError
asyncio/Streams
封裝過的高階串流資料處理介面,不用處理到底層的I/O操作
之所以選用 async 的方式是因為這樣 socket 接收資料的部份可以放在自己的eventLoop裡面,而不是以往的 while True。
可以看一下範例感受一下差別:
import asyncio
async def tcp_echo_client(message, loop):
reader, writer = await asyncio.open_connection('127.0.0.1', 8888,
loop=loop)
print('Send: %r' % message)
writer.write(message.encode())
data = await reader.read(100)
print('Received: %r' % data.decode())
print('Close the socket')
writer.close()
message = 'Hello World!'
loop = asyncio.get_event_loop()
loop.run_until_complete(tcp_echo_client(message, loop))
loop.close()
import asyncio
async def handle_echo(reader, writer):
data = await reader.read(100)
message = data.decode()
addr = writer.get_extra_info('peername')
print("Received %r from %r" % (message, addr))
print("Send: %r" % message)
writer.write(data)
await writer.drain()
print("Close the client socket")
writer.close()
loop = asyncio.get_event_loop()
coro = asyncio.start_server(handle_echo, '127.0.0.1', 8888, loop=loop)
server = loop.run_until_complete(coro)
# Serve requests until Ctrl+C is pressed
print('Serving on {}'.format(server.sockets[0].getsockname()))
try:
loop.run_forever()
except KeyboardInterrupt:
pass
# Close the server
server.close()
loop.run_until_complete(server.wait_closed())
loop.close()