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

PHP socket_recv返回不可读响应,Python与Web服务交互异常

PHP与Python Socket通信响应不可读问题排查与解决

核心问题:socket_recv的flags参数错误

PHP代码中socket_recv使用了0x20(对应MSG_OOB带外数据标志),但Python端发送的是普通TCP数据流,并未发送带外数据。该标志会导致PHP仅尝试读取带外数据,忽略正常响应内容,最终返回无效/乱码数据。

修复步骤

1. 修正socket_recv的flags参数

将0x20替换为0(默认读取普通数据的标志):

while ($bytes = @socket_recv($socket, $response, $max_len, 0)) {
    $total_response .= str_replace($end_line_msg, '', $response);
    if (strstr($response, $end_line_msg)) break;
}

2. 统一结束符逻辑

目前PHP端注释了请求添加结束符的代码,但Python端响应仍拼接end_line,导致结束判断逻辑失效:

  • 取消PHP端// $command .= $end_line_msg;的注释,确保请求末尾携带结束符
  • 保证Python端的end_line与PHP端$end_line_msg完全一致(建议使用ASCII字符如'--END--'避免特殊字符编码冲突)

3. 保障编码一致性

  • Python端发送时明确指定UTF-8编码:
self.transport.write(send.encode('utf-8'))
  • PHP端接收后强制转换为UTF-8编码:
$total_response = mb_convert_encoding($total_response, 'UTF-8', 'auto');

4. 优化Socket关闭时机

Python端发送后立即关闭Socket可能导致PHP端未完成数据接收,可延迟关闭确保数据发送完成:

import asyncio
asyncio.get_event_loop().call_later(0.5, self.transport.close)

修正后的关键代码片段

PHP端接收逻辑

$max_len = 65495;
$total_response = '';
while ($bytes = @socket_recv($socket, $response, $max_len, 0)) {
    $total_response .= str_replace($end_line_msg, '', $response);
    if (strstr($response, $end_line_msg)) break;
}
// 统一编码为UTF-8
$total_response = mb_convert_encoding($total_response, 'UTF-8', 'auto');

Python端发送逻辑

end_line = '«--the-end-line--»'
send = f'{result}{end_line}'
log('Data sending.')
self.transport.write(send.encode('utf-8'))
# 延迟关闭Socket,确保数据完整发送
import asyncio
asyncio.get_event_loop().call_later(0.5, self.transport.close)

内容的提问来源于stack exchange,提问作者Mustafa Ömer Eser

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 06:57:08