使用python asyncio構建的簡單TCP服務器,為何Telnet連接會立即斷開?本文分析一個使用asyncio庫編寫的簡單TCP服務器示例,該服務器在Telnet客戶端連接后立即斷開連接,并解釋其原因及解決方案。代碼使用asyncio.StreamReader和asyncio.StreamWriter處理客戶端連接,但存在一個關鍵問題導致Telnet客戶端連接后立即斷開。
原始代碼如下:
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連接該服務器時,會立即顯示“connection closed by foreign host.” 這是因為reader.readline()方法會阻塞,等待完整的行結束符(通常是rn),而Telnet客戶端可能不會立即發送完整的行。服務器在未收到完整行之前不會執行任何操作,客戶端也收不到任何響應,最終導致服務器關閉連接。
問題的關鍵在于:服務器需要主動發送歡迎信息,使用writer.drain()確保數據寫入,并修改讀取數據的方式避免阻塞等待完整行。改進后的handle_client函數如下:
立即學習“Python免費學習筆記(深入)”;
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) if not data: break writer.write(data) await writer.drain()
通過添加歡迎信息并使用reader.read(100)讀取固定大小的數據,避免了阻塞等待完整行的問題,從而解決了Telnet連接立即斷開的問題。await writer.drain()確保數據寫入網絡緩沖區,避免數據丟失。這使得服務器能夠及時響應客戶端連接,并保持連接的持續性。
? 版權聲明
文章版權歸作者所有,未經允許請勿轉載。
THE END