python asyncio TCP服務(wù)器連接中斷:telnet連接立即斷開及解決方案
本文分析并解決了一個(gè)使用Python asyncio庫構(gòu)建的TCP服務(wù)器在使用telnet連接時(shí)立即斷開的問題。
問題描述:
以下代碼片段展示了一個(gè)簡單的asyncio TCP服務(wù)器:
立即學(xué)習(xí)“Python免費(fèi)學(xué)習(xí)筆記(深入)”;
import asyncio from asyncio.base_events import server async def handle_client(reader, writer): while True: data = await reader.readline() if not data: break writer.write(data) writer.close() async def main(): server: server = await asyncio.get_running_loop().create_server( handle_client, '127.0.0.1', 8888) async with server: await server.serve_forever() asyncio.run(main())
使用telnet連接到該服務(wù)器(127.0.0.1:8888)后,連接會(huì)立即斷開,并顯示”connection closed by foreign host.”錯(cuò)誤信息。
問題分析與解決方案:
問題根源在于handle_client函數(shù)中缺少await writer.drain()調(diào)用。writer.write()僅將數(shù)據(jù)寫入緩沖區(qū),并不保證立即發(fā)送到客戶端。writer.drain()用于等待緩沖區(qū)數(shù)據(jù)完全發(fā)送。telnet客戶端期望立即收到服務(wù)器響應(yīng),而服務(wù)器未及時(shí)發(fā)送數(shù)據(jù),導(dǎo)致telnet認(rèn)為連接已斷開。
解決方案是修改handle_client函數(shù),在writer.write()后添加await writer.drain(),確保數(shù)據(jù)立即發(fā)送:
async def handle_client(reader, writer): welcome_message = "Welcome to the server!n" writer.write(welcome_message.encode()) await writer.drain() while True: data = await reader.read(100) # 使用read(100)更靈活處理數(shù)據(jù) if not data: break writer.write(data) await writer.drain() writer.close()
修改后的代碼在writer.write()后添加了await writer.drain(),并使用reader.read(100)代替reader.readline()以更靈活地處理客戶端數(shù)據(jù),從而解決了telnet連接立即斷開的問題。添加的歡迎消息用于驗(yàn)證連接是否成功建立。
通過這個(gè)修正,服務(wù)器能夠正確地處理客戶端請(qǐng)求并保持連接。