You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Python中使用Socket调用API时无限等待服务器回复问题

解决FIX消息发送后无限等待服务器回复的问题

首先看你的代码,最可能的问题出在FIX消息的分隔符上——标准FIX协议要求用ASCII的SOH字符(也就是\x01)作为字段分隔符,而你用了|,服务器根本没法正确解析你的消息,自然不会给你回复,导致sock.recv()一直处于阻塞等待状态。

接下来给你几个针对性的修复步骤:

1. 替换分隔符为标准SOH字符,重新计算校验和

FIX协议的校验和(第10字段)是基于整个消息内容的,改了分隔符后必须重新计算,否则服务器会判定消息无效直接丢弃。你可以这样构造正确的消息:

import socket

# 先构造核心字段,暂不包含长度和校验和
message_fields = [
    "8=FIX.4.4",
    "35=0",
    "49=theBroker.12345",
    "56=cServer",
    "57=QUOTE",
    "50=BVN's Message",
    "34=1",
    "52=20180322-21:26:01"
]

# 用SOH字符连接字段,计算BodyLength(第9字段)
soh = "\x01"
body = soh.join(message_fields[1:])
body_length = len(body)
message_fields.insert(1, f"9={body_length}")

# 拼接无校验和的消息,计算校验和
message_without_checksum = soh.join(message_fields)
checksum = sum(ord(c) for c in message_without_checksum) % 256
full_message = f"{message_without_checksum}{soh}10={checksum:03d}{soh}"

2. 改进接收逻辑,确保拿到完整回复

你的sock.recv(3)只接收3字节,就算服务器回复了也只能拿到片段,而且FIX消息长度不固定,应该循环接收直到拿到完整的消息:

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('h68.p.ctrader.com',5211)
sock.connect(server_address)

# 发送正确构造的消息
sock.send(bytes(full_message,'utf-8'))

# 循环接收直到完整消息
received_data = b''
while True:
    chunk = sock.recv(1024)
    if not chunk:
        break
    received_data += chunk
    # FIX消息以SOH结尾且包含校验和字段,以此判断是否完整
    if b'10=' in received_data and received_data.endswith(b'\x01'):
        break

print(received_data.decode('utf-8'))
sock.close()

3. 其他需要确认的点

  • 确认你的BrokerID(第49字段)是平台认可的有效ID,无效的客户端标识可能会被服务器静默拒绝,不会返回任何内容。
  • 核实服务器端口是否匹配环境:cTrader的模拟盘和实盘端口可能不同,5211是否对应你要连接的环境需要确认。

最后建议你使用成熟的FIX库(比如quickfix)来处理消息的构造和解析,手动处理很容易在字段长度、校验和这类细节上出错。

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

火山引擎 最新活动