如何在单Python脚本中实现asyncio socket服务端与客户端同时运行及!r语法查询
问题排查
你提供的代码无法同时运行服务端和客户端的核心原因是:
- 原代码仅调用
asyncio.run(main())启动服务端,server.serve_forever()是永久阻塞的协程,客户端逻辑完全没有被事件循环调度 - 要在单文件内同时运行两端,需要将两个逻辑放到同一个事件循环中并发调度,同时需要保证服务端启动完成后再执行客户端连接,避免连接报错
修复后完整可运行代码
import asyncio async def echo_client(msg): reader, writer = await asyncio.open_connection('127.0.0.1',5050) print(f'Send:{msg!r}') writer.write(msg.encode()) await writer.drain() data = await reader.read(100) print(f'Recieved: {data.decode()!r}') print('close the connection') writer.close() await writer.wait_closed() async def handle_echo(reader, writer): data = await reader.read(100) message = data.decode() addr = writer.get_extra_info('peername') print(f'Recieved {message!r} from {addr!r}') print(f'Send:{message!r}') writer.write(data) await writer.drain() print('close the connection') writer.close() async def main(): server = await asyncio.start_server(handle_echo,'127.0.0.1',5050) addr = server.sockets[0].getsockname() print(f'Serving on {addr}') # 异步启动服务端永久运行任务,不阻塞后续客户端执行 server_task = asyncio.create_task(server.serve_forever()) # 短暂等待保证服务端完全启动完成 await asyncio.sleep(0.1) try: # 执行客户端逻辑 await echo_client("hello server") finally: # 客户端运行完成后关闭服务端,避免程序永久挂起 server_task.cancel() await server.wait_closed() asyncio.run(main())
!r格式符作用 !r是Python格式化字符串中的转换符,作用是调用对应对象的__repr__()方法获取其字符串表示,和默认的字符串格式化逻辑区别如下:
- 输出字符串时会自带引号,同时转义所有特殊字符,更适合调试场景,能清晰展示变量的原始内容
- 例如变量
msg = "hello\nworld",f"{msg!r}"的输出为'hello\nworld',可以直接看到转义符\n;如果不使用!r,输出时\n会被解析为真实换行,内容分为两行展示
内容的提问来源于stack exchange,提问作者Surya Mani Pandey
相关产品推荐
相关产品推荐

