Python异步客户端间与服务器间代理失效问题排查求助
代理转发故障排查求助
现有一台设备仅能连接两个远程端口并通过这些连接转发数据,我编写了两个专用代理服务器:一个运行在该设备上,另一个在本地监听两个端口转发数据。但运行异常:访问https://127.0.0.1:4000时,服务器间代理能收到数据,但客户端间代理无数据,无法访问192.168.0.5上的Web服务器。
客户端间代理代码
import asyncio async def forward_data(source_reader, destination_writer): while True: data = await source_reader.read() if not data: break destination_writer.write(data) await destination_writer.drain() destination_writer.close() async def run_server(): reader1, writer1 = await asyncio.open_connection('127.0.0.1', 5000) reader2, writer2 = await asyncio.open_connection('192.168.0.5', 443) await asyncio.gather( forward_data(reader1, writer2), forward_data(reader2, writer1) ) asyncio.run(run_server())
服务器间代理代码
import asyncio async def handle_client(reader, writer): while True: try: data = await reader.read() if not data: break writer.write(data) await writer.drain() except ConnectionResetError as e: print(f"Connection reset by peer: {e}") break writer.close() async def start_server(): server_4000 = await asyncio.start_server(handle_client, '127.0.0.1', 4000) server_5000 = await asyncio.start_server(handle_client, '127.0.0.1', 5000) await asyncio.gather(server_4000.serve_forever(), server_5000.serve_forever()) asyncio.run(start_server())
问题根源
你的代码存在两个核心逻辑错误:
- 服务器间代理的转发逻辑缺失:
handle_client函数仅将收到的数据写回给当前客户端,没有建立到客户端间代理的转发连接,数据根本没传到5000端口。 - 客户端间代理的连接模式错误:启动时直接建立一条固定连接到5000端口和目标服务器,但实际需要为每个来自服务器间代理的请求创建独立转发链路,而非用单连接处理所有请求。
修复后的代码
修复后的服务器间代理代码
import asyncio async def forward_data(source_reader, dest_writer): try: while True: data = await source_reader.read(4096) if not data: break dest_writer.write(data) await dest_writer.drain() finally: dest_writer.close() await dest_writer.wait_closed() async def handle_client(local_reader, local_writer): # 每个客户端连接都新建到客户端间代理的连接 try: remote_reader, remote_writer = await asyncio.open_connection('127.0.0.1', 5000) await asyncio.gather( forward_data(local_reader, remote_writer), forward_data(remote_reader, local_writer) ) except Exception as e: print(f"连接异常: {e}") finally: local_writer.close() await local_writer.wait_closed() async def start_server(): server_4000 = await asyncio.start_server(handle_client, '127.0.0.1', 4000) await server_4000.serve_forever() asyncio.run(start_server())
修复后的客户端间代理代码
import asyncio async def forward_data(source_reader, dest_writer): try: while True: data = await source_reader.read(4096) if not data: break dest_writer.write(data) await dest_writer.drain() finally: dest_writer.close() await dest_writer.wait_closed() async def handle_proxy_connection(proxy_reader, proxy_writer): # 每个中转连接都新建到目标Web服务器的连接 try: target_reader, target_writer = await asyncio.open_connection('192.168.0.5', 443) await asyncio.gather( forward_data(proxy_reader, target_writer), forward_data(target_reader, proxy_writer) ) except Exception as e: print(f"转发异常: {e}") finally: proxy_writer.close() await proxy_writer.wait_closed() async def run_proxy(): server = await asyncio.start_server(handle_proxy_connection, '127.0.0.1', 5000) await server.serve_forever() asyncio.run(run_proxy())
修复说明
- 服务器间代理:每收到一个客户端(4000端口)请求,就新建到客户端间代理5000端口的连接,双向转发数据实现中转。
- 客户端间代理:监听5000端口,每收到中转连接就新建到目标Web服务器的连接,完成最终请求转发。
- 补充
wait_closed()确保连接正确关闭,用read(4096)分块读取数据提升稳定性。
内容的提问来源于stack exchange,提问作者ratel
相关产品推荐
相关产品推荐

