插入Unicode字符到SQLite后Python3程序假死问题求助
嘿,这个问题我之前踩过坑!大概率是原生消息通信时的编码和长度计算不匹配导致的Python假死,咱们一步步来解决:
问题核心原因
Firefox和原生程序的原生消息协议有严格的格式要求:
每条消息由「4字节小端无符号整数(表示后续JSON字符串的UTF-8字节数)」 + 「UTF-8编码的JSON字符串」组成
当消息包含西里尔字母这类非ASCII字符时,每个字符会占用2~4个UTF-8字节。如果你的Python代码错误地用字符数代替UTF-8字节数来计算消息长度,就会导致程序一直等待“缺失”的字节,最终表现为假死。
解决方案步骤
1. 修复Python端的消息接收逻辑
确保你是按二进制方式读取stdin,并且正确解析长度前缀:
import struct import sys import json # 切换stdin/stdout为二进制模式(Windows下尤其重要) sys.stdin = open(sys.stdin.fileno(), 'rb') sys.stdout = open(sys.stdout.fileno(), 'wb') def receive_message(): # 读取4字节的长度前缀(小端无符号整数) length_bytes = sys.stdin.read(4) if not length_bytes: return None # 解析长度 message_length = struct.unpack('<I', length_bytes)[0] # 读取对应字节数的消息内容 message_bytes = sys.stdin.read(message_length) # 用UTF-8解码为字符串,再解析JSON return json.loads(message_bytes.decode('utf-8')) # 接收消息循环 while True: msg = receive_message() if not msg: break print(f"Received data: {msg}") # 执行数据写入SQLite的逻辑 # ...
2. 确保Python端的响应发送逻辑正确
给Firefox回消息时,同样要遵循协议格式,并且强制刷新输出缓冲区(否则数据可能卡在缓冲区里,导致扩展收不到响应):
def send_response(response_data): # 序列化为JSON字符串,再转成UTF-8字节 response_json = json.dumps(response_data) response_bytes = response_json.encode('utf-8') # 写入4字节长度前缀 sys.stdout.write(struct.pack('<I', len(response_bytes))) # 写入响应内容 sys.stdout.write(response_bytes) # 必须flush,否则数据不会立即发送 sys.stdout.flush()
3. 检查Firefox扩展端的发送逻辑
如果你的扩展是手动处理消息编码,一定要确保用UTF-8计算字节长度。不过更推荐直接用browser.runtime.sendNativeMessage传入JavaScript对象——Firefox会自动帮你完成JSON序列化、UTF-8编码和长度前缀的处理:
// 直接传对象即可,Firefox会自动处理编码和长度 browser.runtime.sendNativeMessage('你的原生应用ID', { data: 'Привет, мир!' // 包含西里尔字母的测试数据 }).then(response => { console.log('收到响应:', response); }).catch(error => { console.error('发送失败:', error); });
4. 排查SQLite写入的潜在问题
如果前面的步骤都没问题,还要确认SQLite数据库的编码是否为UTF-8。创建数据库时可以指定编码:
import sqlite3 conn = sqlite3.connect('your_db.db') # 确保连接使用UTF-8编码 conn.execute('PRAGMA encoding = "UTF-8"')
测试验证
构造一个包含非ASCII字符的测试消息,比如{"content": "Привет, это тест с кириллицей!"},运行Python程序和扩展,观察Python是否能正常接收、处理并响应,不会出现假死。
内容的提问来源于stack exchange,提问作者Endyl
相关产品推荐
相关产品推荐

