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

Java通过Socket发送JSON至Python服务端,json.loads解析失败求助

Java Socket发送JSON到Python服务端,json.loads解码失败

Java端构造JSONObject后通过Socket发送,Python服务端能接收数据,但调用json.loads()时抛出JSONDecodeError,无法转换为字典处理。

Java代码

JSONObject obj = new JSONObject();
Socket clientSocket;
[...]
clientSocket = new Socket(Server.getOrchestrator(), 5051);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
obj.put("operation", "provider list");
outToServer.writeUTF(obj.toString());

Python代码

socket = (socket configuration here)
socket.listen(5)
client, address = socket.accept()
threading.Thread(target=self.serve_client, args=(client, address)).start()
def serve_client(self, client, address):
    SIZE = 1024
    while True:
        recv_data = client.recv(SIZE).decode('utf-8')
        print(recv_data)
        print(type(recv_data))
        recv_data = json.loads(recv_data) # <-- 此处报错

报错信息

error JSONDecodeError('Expecting value: line 1 column 1 (char 0)',)

解码前的接收数据

b'\x00\x1d{"operation":"provider list"}'

尝试过的解决方法

Java端尝试

替换DataOutputStream为以下方式,但程序挂起,Python无接收内容:

OutputStreamWriter outToServer = new OutputStreamWriter (clientSocket.getOutputStream(), StandardCharsets.UTF_8);
BufferedReader outToServer = new BufferedReader(new OutputStreamWriter(clientSocket.getOutputStream(), StandardCharsets.UTF_8));

Python端尝试

尝试1:

recv_data = client.recv(SIZE) # 未解码,为字节类型
recv_data = json.dumps(recv_data) # 因无法处理字节报错
recv_data = json.loads(recv_data)

尝试2:

recv_data = client.recv(SIZE).decode('utf-8')
recv_data = json.dumps(recv_data) # 执行成功
print(f"String recv_data converted in string: {recv_data}\nRecv_data type {type(recv_data)})
recv_data = json.loads(recv_data) # 未返回字典,仍为字符串
print(f"String recv_data converted in dictionary: {recv_data}\nRecv_data type {type(recv_data)})

尝试2的输出:

{"operation":"provider list"}
<class 'str'>
String recv_data converted in string: "\u0000\u001d{\"operation\":\"provider list\"}"
Recv_data tyoe: <class 'str'>
String recv_data converted in a dictionary: {"operation": "provider list"}
Recv_data type: <class 'str'>

问题根源

DataOutputStream.writeUTF()会在字符串前添加2字节的UTF-8长度前缀(你收到的b'\x00\x1d'就是这个前缀,0x1d对应29,是后面JSON字符串的长度),Python的recv()会把这个前缀一起读入,导致JSON解析器无法识别有效JSON起始位置,抛出错误。

解决方案

方案1:修改Java发送逻辑(推荐)

放弃DataOutputStream.writeUTF(),直接用OutputStreamWriter发送UTF-8编码的JSON字符串,避免自动添加长度前缀,同时必须调用flush()确保数据发送:

JSONObject obj = new JSONObject();
Socket clientSocket = new Socket(Server.getOrchestrator(), 5051);
// 直接用UTF-8编码的输出流发送
OutputStreamWriter outToServer = new OutputStreamWriter(clientSocket.getOutputStream(), StandardCharsets.UTF_8);
obj.put("operation", "provider list");
outToServer.write(obj.toString());
outToServer.flush(); // 关键:强制将缓冲区数据发送出去
// 按需关闭资源
// outToServer.close();
// clientSocket.close();

方案2:Python端兼容长度前缀

如果无法修改Java代码,Python端需要先读取前2字节的长度前缀,再读取对应长度的JSON数据:

def serve_client(self, client, address):
    while True:
        # 先读取2字节的长度前缀
        len_prefix = client.recv(2)
        if not len_prefix:
            break  # 连接断开
        # 将2字节前缀转为整数(大端字节序,对应Java writeUTF的格式)
        data_length = int.from_bytes(len_prefix, byteorder='big')
        # 读取指定长度的JSON数据(若数据量大需循环读取)
        recv_data = b''
        while len(recv_data) < data_length:
            chunk = client.recv(data_length - len(recv_data))
            if not chunk:
                break
            recv_data += chunk
        # 解码并解析JSON
        json_data = json.loads(recv_data.decode('utf-8'))
        print(json_data, type(json_data))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 20:00:16