You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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())

问题根源

你的代码存在两个核心逻辑错误:

  1. 服务器间代理的转发逻辑缺失:handle_client函数仅将收到的数据写回给当前客户端,没有建立到客户端间代理的转发连接,数据根本没传到5000端口。
  2. 客户端间代理的连接模式错误:启动时直接建立一条固定连接到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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 19:47:51