C#多进程启动Python Socket服务时,JSON服务进程异常终止的问题排查
C#多进程启动Python Socket服务时,JSON服务进程异常终止的问题排查
嗨,我来帮你排查这个问题!从你描述的现象和贴出的代码来看,咱们可以从几个核心方向入手分析和解决:
一、先排查最常见的「进程输出缓冲区阻塞」问题
C#启动外部进程(比如Python脚本)时,默认不会处理进程的标准输出和错误输出。当Python脚本输出的内容填满系统缓冲区后,进程会被强制阻塞甚至直接终止——这是多进程启动场景里的高频坑点。
解决办法:修改C#代码,重定向并处理输出
给每个Process实例添加输出/错误重定向逻辑,避免缓冲区溢出,同时还能看到Python脚本的运行日志,方便定位问题:
if (!string.IsNullOrEmpty(ipAddress)) { string script1Path = "serveri.py"; string script2Path = "serjson20.py"; string script3Path = "serjson5.py"; string arguments = ipAddress; // 封装一个创建Python进程的辅助方法,避免重复代码 Process CreatePythonProcess(string scriptPath) { var process = new Process(); process.StartInfo.FileName = "python"; process.StartInfo.Arguments = $"{scriptPath} {arguments}"; // 开启输出重定向 process.StartInfo.RedirectStandardOutput = true; process.StartInfo.RedirectStandardError = true; process.StartInfo.UseShellExecute = false; process.StartInfo.CreateNoWindow = true; // 处理输出和错误日志 process.OutputDataReceived += (sender, e) => { if (!string.IsNullOrEmpty(e.Data)) Console.WriteLine($"[{scriptPath}] {e.Data}"); }; process.ErrorDataReceived += (sender, e) => { if (!string.IsNullOrEmpty(e.Data)) Console.WriteLine($"[{scriptPath} ERROR] {e.Data}"); }; return process; } var process1 = CreatePythonProcess(script1Path); var process2 = CreatePythonProcess(script2Path); var process3 = CreatePythonProcess(script3Path); process1.Start(); process1.BeginOutputReadLine(); process1.BeginErrorReadLine(); process2.Start(); process2.BeginOutputReadLine(); process2.BeginErrorReadLine(); process3.Start(); process3.BeginOutputReadLine(); process3.BeginErrorReadLine(); }
二、修复Python代码中「未捕获的异常」问题
你的Python脚本里,receive_image和receive_json函数没有做异常捕获,一旦文件写入、Socket接收等操作出错,异常会直接扩散到外层的start_server函数,触发finally块关闭Socket并终止进程——这正好符合你描述的「当图片服务开始接收时,JSON服务进程停止」的现象(比如两者同时写入同一个chche文件夹时,可能出现文件占用或权限错误)。
解决办法:给Python的接收函数添加异常捕获
以serjson5.py的receive_json为例,修改后如下:
def receive_json(client_socket, save_folder): try: # 确保保存文件夹存在,避免创建失败 os.makedirs(save_folder, exist_ok=True) # Receive the size of the json size_data = client_socket.recv(4) if not size_data: print("Client closed connection before sending JSON size") return json_size = struct.unpack("!I", size_data)[0] # Receive the json data json_data = b"" while len(json_data) < json_size: data = client_socket.recv(json_size - len(json_data)) if not data: break json_data += data if len(json_data) == json_size: # Get the original json name from the client json_name = client_socket.recv(1024).decode().strip() # 去除多余空格/换行 # Save the received json save_path = os.path.join(save_folder, json_name) with open(save_path, "wb") as file: file.write(json_data) print(f"Json received and saved as {save_path}") else: print("Incomplete Json data received") except Exception as e: print(f"Error receiving JSON: {str(e)}") finally: # 确保客户端Socket被正确关闭 try: client_socket.close() except: pass
同样的逻辑也需要应用到serveri.py的receive_image函数上,避免单个请求的错误导致整个服务进程终止。
三、额外验证点
- 确认三个Python脚本使用的端口(5500、5501、5502)没有被其他程序占用,可以用
netstat -ano | findstr 端口号命令检查。 - 验证
chche文件夹的读写权限,确保三个Python进程都能正常写入文件。
按照上面的步骤修改后,你应该能看到Python进程的详细运行日志,也能避免单个请求的错误导致整个服务崩溃。
备注:内容来源于stack exchange,提问作者ray_conclusion
相关产品推荐
相关产品推荐

