需要在VM的C#脚本设置string类型Out变量和float类型OutF变量,python的输出信息会在Out变量显示
csharp
using System;
using System.IO;
using Script.Methods;
using System.Diagnostics;
using System.Net.Sockets;
using System.Text;
using System.Threading;
public partial class UserScript : ScriptMethods, IProcessMethods
{
private PythonTcpRunner _pythonRunner;
private Process _pythonProcess; // 保持进程引用
public new int nErrorCode;
private string pythonEdio=@"C:\T\python.exe";
private string python= @"C:\T\清晰度评估.py";
/// <summary>
/// 初始化:启动Python进程并建立TCP连接
/// </summary>
public void Init()
{
// 初始化TCP运行器(使用本地8888端口)
_pythonRunner = new PythonTcpRunner(
pythonEdio,
python,
"127.0.0.1",
8888
);
// 启动Python进程并等待TCP服务就绪
string errorMsg;
if (!_pythonRunner.StartProcess(out _pythonProcess, out errorMsg))
{
nErrorCode = -1;
Out = "初始化Python进程失败: " + errorMsg;
}
}
/// <summary>
/// 执行流程:通过TCP发送请求
/// </summary>
public bool Process()
{
try
{
// 检查进程状态
if (_pythonProcess == null || _pythonProcess.HasExited)
{
string errorMsg;
if (!_pythonRunner.RestartProcess(out _pythonProcess, out errorMsg))
{
nErrorCode = -1;
Out = "重启Python进程失败: " + errorMsg;
return false;
}
}
// 通过TCP发送执行请求
string errorMessage;
string outputMessage;
bool success = _pythonRunner.SendRequest("EXECUTE", out errorMessage, out outputMessage, 5000);
Out = string.IsNullOrWhiteSpace(outputMessage) ? errorMessage : outputMessage;
// 尝试将输出转换为float并赋值给OutF
float result;
if (!float.TryParse(outputMessage, out result))
{
// 如果转换失败,设置为NaN或其他默认值
OutF = float.NaN;
}
else
{
OutF = result;
}
if (!success)
{
nErrorCode = -2;
return false;
}
nErrorCode = 0;
return true;
}
catch (Exception ex)
{
nErrorCode = -3;
Out = string.Format("执行异常: {0}", ex.Message);
return false;
}
}
/// <summary>
/// 释放资源:关闭进程和连接,使用override关键字重写基类方法
/// </summary>
public override void Dispose()
{
// 发送退出指令(修复输出参数错误,兼容.NET 4.6)
if (_pythonRunner != null)
{
string dummyError;
string dummyOutput;
_pythonRunner.SendRequest("EXIT", out dummyError, out dummyOutput, 1000);
}
if (_pythonProcess != null && !_pythonProcess.HasExited)
{
try
{
_pythonProcess.WaitForExit(2000);
if (!_pythonProcess.HasExited)
_pythonProcess.Kill();
}
catch { }
finally
{
_pythonProcess.Dispose();
_pythonProcess = null;
}
}
// 关闭连接(兼容.NET 4.6)
if (_pythonRunner != null)
{
_pythonRunner.Close();
}
// 调用基类的Dispose方法
base.Dispose();
}
}
/// <summary>
/// 基于TCP的Python运行器
/// </summary>
public class PythonTcpRunner
{
private string _pythonPath;
private string _scriptPath;
private string _ip;
private int _port;
private TcpClient _client;
public PythonTcpRunner(string pythonPath, string scriptPath, string ip, int port)
{
_pythonPath = pythonPath;
_scriptPath = scriptPath;
_ip = ip;
_port = port;
}
/// <summary>
/// 启动Python进程
/// </summary>
public bool StartProcess(out Process process, out string errorMessage)
{
errorMessage = string.Empty;
process = null;
try
{
var startInfo = new ProcessStartInfo
{
FileName = _pythonPath,
Arguments = string.Format("\"{0}\" {1} {2}", _scriptPath, _ip, _port),
UseShellExecute = false,
CreateNoWindow = true,
WorkingDirectory = Path.GetDirectoryName(_scriptPath)
};
process = Process.Start(startInfo);
if (process == null)
{
errorMessage = "无法启动Python进程";
return false;
}
// 等待TCP服务启动(最多等3秒)
int retry = 0;
while (retry < 30)
{
try
{
_client = new TcpClient();
var result = _client.BeginConnect(_ip, _port, null, null);
var success = result.AsyncWaitHandle.WaitOne(100);
if (success)
{
_client.EndConnect(result);
return true;
}
}
catch { }
retry++;
Thread.Sleep(100);
}
errorMessage = "Python TCP服务启动超时";
process.Kill();
return false;
}
catch (Exception ex)
{
errorMessage = ex.Message;
return false;
}
}
/// <summary>
/// 重启进程
/// </summary>
public bool RestartProcess(out Process process, out string errorMessage)
{
Close();
return StartProcess(out process, out errorMessage);
}
/// <summary>
/// 发送TCP请求
/// </summary>
public bool SendRequest(string command, out string errorMessage, out string outputMessage, int timeout)
{
errorMessage = string.Empty;
outputMessage = string.Empty;
try
{
if (_client == null || !_client.Connected)
{
errorMessage = "TCP连接已断开";
return false;
}
var stream = _client.GetStream();
stream.ReadTimeout = timeout;
stream.WriteTimeout = timeout;
// 发送指令(UTF8编码,以换行符结束)
byte[] data = Encoding.UTF8.GetBytes(command + "\n");
stream.Write(data, 0, data.Length);
// 读取响应(直到收到结束标记)
using (var ms = new MemoryStream())
{
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, bytesRead);
// 检查是否包含结束标记
string temp = Encoding.UTF8.GetString(ms.ToArray());
if (temp.Contains("\nEOF\n"))
{
outputMessage = temp.Replace("\nEOF\n", "").Trim();
return true;
}
}
}
errorMessage = "未收到完整响应";
return false;
}
catch (Exception ex)
{
errorMessage = ex.Message;
return false;
}
}
/// <summary>
/// 关闭连接
/// </summary>
public void Close()
{
try
{
if (_client != null)
{
_client.Close();
}
}
catch { }
_client = null;
}
}
python
import sys
import time
import socket
# 简单的数字运算函数
def simple_calculation(input_num):
result = (input_num ** 2) + (input_num * 1.5) - 42
time.sleep(0.1)
return round(result, 2)
# 简化的TCP服务器
class SimpleServer:
def __init__(self, host, port):
self.host = host
self.port = port
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server_socket.bind((host, port))
self.server_socket.listen(1)
self.running = True
self.client_socket = None
self.test_numbers = [12, 34, 56, 78, 90]
def handle_client(self):
while self.running and self.client_socket:
try:
data = self.client_socket.recv(1024).decode('utf-8').strip()
if not data:
break
if data == "EXECUTE":
result = self.process_numbers()
self.client_socket.sendall((result + "\nEOF\n").encode('utf-8'))
elif data == "EXIT":
self.running = False
self.client_socket.sendall("已退出\nEOF\n".encode('utf-8'))
break
else:
self.client_socket.sendall(("未知指令\nEOF\n").encode('utf-8'))
except Exception as e:
error_msg = f"处理请求出错: {str(e)}\nEOF\n"
self.client_socket.sendall(error_msg.encode('utf-8'))
break
def process_numbers(self):
total_start = time.perf_counter()
results = []
for num in self.test_numbers:
try:
result = simple_calculation(num)
results.append(f"数字 {num} 的计算结果: {result}")
except Exception as e:
results.append(f"错误: {str(e)}")
total_elapsed = time.perf_counter() - total_start
results.append(f"\n总处理时间: {total_elapsed:.4f}秒")
return "\n".join(results)
def start(self):
print(f"TCP服务器启动在 {self.host}:{self.port}")
try:
self.client_socket, addr = self.server_socket.accept()
print(f"客户端 {addr} 已连接")
self.handle_client()
finally:
self.stop()
def stop(self):
if self.client_socket:
self.client_socket.close()
self.server_socket.close()
print("服务器已停止")
if __name__ == "__main__":
if len(sys.argv) != 3:
print("用法: python simple_server.py [host] [port]")
sys.exit(1)
host = sys.argv[1]
port = int(sys.argv[2])
server = SimpleServer(host, port)
try:
server.start()
except KeyboardInterrupt:
server.stop()
sys.exit(0)