You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

  1. 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.
  2. Socket Closure: The __del__ method isn’t guaranteed to run immediately, so connections and sockets might linger as resources.
  3. Uninitialized Variable: You had univariate_future_target commented 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

  1. Reliable Result Transmission:

    • Used sendall() instead of send() 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).
  2. Proper Socket Closure:

    • Added a finally block 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).
  3. Model Fix:

    • Initialized univariate_future_target to avoid a runtime error.
    • Wrapped ast.literal_eval() in a try/except block to handle malformed input more gracefully.
  4. Error Handling:

    • Returned JSON-formatted errors so MT4 can parse failures consistently.

内容的提问来源于stack exchange,提问作者Beertje

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:42:33