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




