Python Socket客户端与服务端同时运行时性能骤降求助
问题分析与解决方案
可能的原因
- FPGA端LwIP资源瓶颈:FPGA上的LwIP属于轻量级TCP/IP实现,通常仅支持单线程或有限并发处理能力。当同时处理主机
server.py的接收(FPGA发数据到主机)和client.py的发送(主机发数据到FPGA)时,LwIP的缓冲区、软核CPU资源会被占满,无法及时响应主机客户端的TCP窗口更新,导致client.py的sendall频繁阻塞,吞吐量暴跌。 - 主机端进程调度与IO竞争:两个Python进程在同一主机运行时,会抢占网卡IO资源和CPU时间片。即便Python独立进程的GIL互不影响,CPU调度的频繁切换也会降低发送效率;同时网卡收发队列若被其中一个进程占满,另一个进程的数据包会被延迟处理。
- TCP流量控制触发:当FPGA端接收缓冲区不足时,会通过缩小TCP窗口告知主机客户端停止发送。如果LwIP的接收缓冲区配置过小,或者数据包处理速度跟不上,就会导致主机客户端的发送窗口频繁被关闭,造成吞吐量大幅波动。
解决方案
- 优化FPGA端LwIP配置
- 增大LwIP的TCP接收缓冲区大小,确保能容纳更多待处理数据包。
- 开启TCP_NODELAY选项,禁用Nagle算法,减少小数据包的传输延迟(适合大流量连续发送场景)。
- 若FPGA使用软核处理器,尝试分配更多CPU时间给LwIP线程,或启用多线程处理TCP连接(需LwIP支持)。
- 主机端程序优化
- 给两个Python进程绑定不同CPU核心,减少调度竞争。比如Linux下用
taskset命令:taskset -c 0 python3 client.py和taskset -c 1 python3 server.py。 - 在
client.py和server.py中开启TCP_NODELAY:from socket import IPPROTO_TCP, TCP_NODELAY # socket创建完成后添加 CLIENT_SOCK.setsockopt(IPPROTO_TCP, TCP_NODELAY, 1) - 尝试非阻塞IO模型,配合
select/epoll处理socket,避免阻塞式sendall/recv导致的进程挂起。比如client.py可修改为:CLIENT_SOCK.setblocking(False) total_sent = 0 send_len = len(send_data) while total_sent < send_len: try: sent = CLIENT_SOCK.send(send_data[total_sent:]) if sent == 0: raise RuntimeError("socket connection broken") total_sent += sent except BlockingIOError: pass - 用
ss -ti dst 192.168.1.10查看client.py连接的窗口大小、重传次数,确认是否存在窗口收缩或重传问题。
- 给两个Python进程绑定不同CPU核心,减少调度竞争。比如Linux下用
- 验证双向带宽上限
- 用
iperf3工具测试双向流量:主机运行iperf3 -s,FPGA端运行iperf3 -c 192.168.1.1 -t 60;同时主机运行iperf3 -c 192.168.1.10 -t 60,观察双向总吞吐量是否接近千兆以太网上限。如果iperf也出现同样问题,说明瓶颈在FPGA端或网络链路;若iperf正常,则问题出在Python程序实现上。
- 用
内容的提问来源于stack exchange,提问作者efe373
相关产品推荐
相关产品推荐

