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

Python通过SSL调用API时响应不完整,JSON解码失败求助

问题分析与解决

你的核心错误是误解了TCP socket的recv()行为:TCP是面向流的协议,数据会被拆分成多个TCP段发送,单次recv()只能返回当前内核缓冲区中可用的部分数据——哪怕你设置了超大的缓冲区,也无法保证一次性拿到完整的响应。你看到的13680字符就是单次recv()能获取的最大可用数据量,剩余数据还在传输或等待接收。

正确的处理方式

必须循环接收数据,直到确认拿到了完整的响应。具体实现可以根据API的通信约定选择以下方案:

方案1:基于约定的结束符(如\n)

如果API响应和你的请求一样,以换行符\n作为结束标记,可以循环接收直到读取到该符号:

request = json.dumps(request) + "\n"
connection.sendall(request.encode())

response_data = b""
while True:
    # 使用固定合理的缓冲区大小(如4096)即可,无需与n_data绑定
    chunk = connection.recv(4096)
    if not chunk:
        # 连接被对方关闭,无更多数据
        break
    response_data += chunk
    # 检查当前块是否包含结束符,包含则停止接收
    if b"\n" in chunk:
        break

# 去掉末尾的换行符后解码解析
response = response_data.decode().strip()
print(len(response))
response = json.loads(response)

方案2:基于JSON解析成功的判断

如果没有明确的结束符,可以尝试循环接收直到JSON能成功解析(不完整的JSON会抛出JSONDecodeError):

import json

request = json.dumps(request) + "\n"
connection.sendall(request.encode())

response_data = b""
while True:
    chunk = connection.recv(4096)
    if not chunk:
        raise ConnectionError("API连接提前关闭,未收到完整响应")
    response_data += chunk
    try:
        # 尝试解码并解析JSON
        response_str = response_data.decode()
        response = json.loads(response_str)
        # 解析成功,说明数据完整,跳出循环
        break
    except json.JSONDecodeError:
        # 解析失败,继续接收更多数据
        continue

print(len(response_str))

额外提示

  • 不要将recv()的缓冲区大小与请求的n_data绑定,固定使用4096或8192这类通用大小即可,过大的缓冲区不会提升接收完整性,只会占用更多内存。
  • SSL socket的接收逻辑和普通TCP socket完全一致,流式协议的特性不会因SSL加密而改变。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 19:53:19