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
相关产品推荐
相关产品推荐

