Python通过subprocess调用C++ Socket服务器遇连接拒绝问题求助
解决Socket客户端调用子进程服务器时的ConnectionRefusedError问题
问题现象
用g++ server_min.cpp -o server编译C++服务器后,单独在终端运行服务器和Python客户端可正常交互,但在Python客户端中通过subprocess.Popen启动服务器时,客户端抛出ConnectionRefusedError: [Errno 111] Connection refused错误。从错误输出顺序能看到:客户端先尝试连接并崩溃,服务器的[LISTENING]日志才随后出现。
原因分析
subprocess.Popen启动子进程后,父进程(Python客户端)会立即执行后续代码,而服务器进程需要完成Socket创建、端口绑定、进入监听状态这一系列初始化步骤才能接受连接。此时客户端发起连接时,服务器还未准备就绪,导致连接被拒绝。
解决方案
方法1:添加固定等待时间
在启动服务器后,让客户端暂停一段时间,给服务器足够的初始化周期。修改嵌入服务器调用的Python代码:
import socket import subprocess, time, os, io, sys, stat, copy from subprocess import Popen, PIPE, STDOUT IP = "127.0.0.1" PORT = 4456 ADDR = (IP,PORT) SIZE = 1024 FORMAT = "utf-8" if __name__ == "__main__": # 启动服务器 run_pro = subprocess.Popen('./server', shell=False, stdout=PIPE, stderr=subprocess.STDOUT, text=True) sys.stdout.flush() # 等待服务器完成初始化(时间可根据实际环境调整) time.sleep(1) print("This is client!!!!!") ep = 0 while(True): client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect(ADDR) data = client.recv(SIZE).decode(FORMAT) print(f"[SERVER] {data}") if(ep == 4): meg = "Done" else: meg = "Continue...ep="+str(ep) client.send(meg.encode(FORMAT)) client.close() if(meg == "Done"): break ep+=1 run_pro.wait() print("End Program!!!!!") print("*******************************************************")
方法2:监听服务器就绪信号(更可靠)
通过读取服务器的标准输出,等待服务器打印[LISTENING]日志后再发起连接,避免固定等待时间的不确定性:
import socket import subprocess, time, os, io, sys, stat, copy from subprocess import Popen, PIPE, STDOUT IP = "127.0.0.1" PORT = 4456 ADDR = (IP,PORT) SIZE = 1024 FORMAT = "utf-8" if __name__ == "__main__": # 启动服务器并捕获输出 run_pro = subprocess.Popen('./server', shell=False, stdout=PIPE, stderr=subprocess.STDOUT, text=True) # 等待服务器输出监听就绪信号 while True: line = run_pro.stdout.readline() if "[LISTENING]" in line: print(line.strip()) break print("This is client!!!!!") ep = 0 while(True): client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client.connect(ADDR) data = client.recv(SIZE).decode(FORMAT) print(f"[SERVER] {data}") if(ep == 4): meg = "Done" else: meg = "Continue...ep="+str(ep) client.send(meg.encode(FORMAT)) client.close() if(meg == "Done"): break ep+=1 run_pro.wait() print("End Program!!!!!") print("*******************************************************")
补充说明
- 方法1实现简单,但依赖固定等待时间,若服务器初始化耗时较长(如复杂运行环境)可能失效;方法2通过监听实际就绪信号,适配性更强。
- 启动服务器时建议捕获
stdout/stderr,便于排查服务器启动过程中的潜在问题。
内容的提问来源于stack exchange,提问作者Aom Sank
相关产品推荐
相关产品推荐

