Python中如何回传结果并关闭Socket?MT4-TensorFlow项目求助
Hey there! Let's work through your socket result transmission and cleanup issues together. I’ve reviewed your code and identified a few key adjustments to make your workflow reliable and ensure proper socket closure.
Key Issues in Your Current Code
- Result Transmission: Your current setup waits for the client (MT4) to close the connection before sending the prediction, which means MT4 might not receive the response at all.
- Socket Closure: The
__del__method isn’t guaranteed to run immediately, so connections and sockets might linger as resources. - Uninitialized Variable: You had
univariate_future_targetcommented out, which would break the model calculation.
Revised Code with Fixes
Here’s the updated code with explanations for each change:
from __future__ import absolute_import, division, print_function, unicode_literals import tensorflow as tf import matplotlib as mpl import matplotlib.pyplot as plt import numpy as np import os import pandas as pd import socket import ast import json mpl.rcParams['figure.figsize'] = (8, 6) mpl.rcParams['axes.grid'] = False TRAIN_SPLIT = 500 tf.random.set_seed(13) def univariate_data(dataset, start_index, end_index, history_size, target_size): data = [] labels = [] start_index = start_index + history_size if end_index is None: end_index = len(dataset) - target_size for i in range(start_index, end_index): indices = range(i-history_size, i) data.append(np.reshape(dataset[indices], (history_size, 1))) labels.append(dataset[i+target_size]) return np.array(data), np.array(labels) def train_test_model(msg=''): msg = msg.replace('true', 'True') try: msg = ast.literal_eval(msg) except: # Return JSON-formatted error for consistency return json.dumps({"error": "BAD JSON!!"}) if isinstance(msg, dict): input_data = msg else: return json.dumps({"error": "BAD JSON!!"}) uni_data = pd.DataFrame(input_data['Data']) uni_data.index = input_data['Time'] uni_data = uni_data.astype('float64') uni_data = uni_data.values uni_train_mean = uni_data[:TRAIN_SPLIT].mean() uni_train_std = uni_data[:TRAIN_SPLIT].std() uni_data = (uni_data - uni_train_mean) / uni_train_std univariate_past_history = 20 univariate_future_target = 0 # Initialize this variable to avoid errors x_train_uni, y_train_uni = univariate_data(uni_data, 0, TRAIN_SPLIT, univariate_past_history, univariate_future_target) responseJSON = {'Pred': str(y_train_uni[0])} return json.dumps(responseJSON) class socketserver: def __init__(self, address='', port=9090): self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.address = address self.port = port self.sock.bind((self.address, self.port)) self.cummdata = '' def recvmsg(self): self.sock.listen(1) self.conn, self.addr = self.sock.accept() print('Connected to', self.addr) self.cummdata = '' try: # Set a timeout to avoid infinite waiting for data self.conn.settimeout(5) while True: try: data = self.conn.recv(1024) # Use a reasonable buffer size if not data: break self.cummdata += data.decode("utf-8") except socket.timeout: # Timeout means we've received all data from MT4 break # Generate and send response immediately after processing response = train_test_model(self.cummdata) self.conn.sendall(response.encode("utf-8")) # sendall() ensures full data transmission print("Prediction sent to client") except Exception as e: print(f"Error handling client: {str(e)}") finally: # Always close the client connection to free resources self.conn.close() print("Client connection closed") return self.cummdata def close_server(self): # Explicit method to close the server socket self.sock.close() print("Server socket closed") # Run the server with graceful shutdown serv = socketserver('127.0.0.1', 9090) print('Socket created at {}. Waiting for client..'.format(serv.sock.getsockname())) try: while True: msg = serv.recvmsg() except KeyboardInterrupt: # Allow graceful shutdown with Ctrl+C print("\nShutting down server...") finally: serv.close_server()
What Changed & Why
Reliable Result Transmission:
- Used
sendall()instead ofsend()to guarantee all prediction data is sent to MT4. - Processed and sent the response immediately after receiving all data (using a timeout to detect when MT4 finishes sending).
- Used
Proper Socket Closure:
- Added a
finallyblock to close the client connection every time, even if an error occurs. - Added an explicit
close_server()method to shut down the server socket gracefully when you stop the script (e.g., with Ctrl+C).
- Added a
Model Fix:
- Initialized
univariate_future_targetto avoid a runtime error. - Wrapped
ast.literal_eval()in a try/except block to handle malformed input more gracefully.
- Initialized
Error Handling:
- Returned JSON-formatted errors so MT4 can parse failures consistently.
内容的提问来源于stack exchange,提问作者Beertje
相关产品推荐
相关产品推荐

