Python3终端可运行的Socket代码,脚本执行报BlockingIOError错误求助
在Linux终端直接进入Python3 CLI执行以下Socket代码时,能正常向传感器的netcat服务器发送命令并收到返回值:
#! /usr/bin/python3 import socket import time s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('192.168.50.30', 7501)) s.setblocking(True) snd = s.send(b'\x00\x0dget_sensor_info') rec = s.recv(1024, 0x40) print(rec)
但将这段代码保存为脚本(如test_sensor.py),通过python3 test_sensor.py执行时,却抛出错误:
Traceback (most recent call last): File "ouster_uptimme.py", line 9,
in
rec = s.recv(1024, 0x40) BlockingIOError: [Errno 11] Resource temporarily unavailable
推测可能与时序或权限相关,寻求解决思路。
1. 修正recv的flags参数
你在recv中使用的0x40对应MSG_DONTWAIT(强制非阻塞模式),这个参数会临时覆盖之前设置的s.setblocking(True)。CLI交互时执行节奏慢,服务器已返回数据,所以未触发错误;脚本执行速度快,数据尚未到达,就触发了非阻塞的资源不可用错误。
修复方式:去掉该flags参数,改用默认的阻塞模式接收:
rec = s.recv(1024) # 或者明确指定flags为0(阻塞模式) rec = s.recv(1024, 0)
2. 增加发送后的等待延迟
脚本执行速度远快于CLI交互,可能发送命令后传感器还未完成响应,直接调用recv会因为无数据可读报错。在send后添加短暂延迟,给传感器足够的响应时间:
snd = s.send(b'\x00\x0dget_sensor_info') time.sleep(0.2) # 可根据传感器实际响应速度调整延迟时长 rec = s.recv(1024)
3. 确保脚本与CLI执行环境一致
- 检查Python版本:分别在CLI执行
python3 --version,在脚本开头添加import sys; print(sys.version),确认两者版本完全一致。 - 对比环境变量:在CLI执行
env,在脚本中添加import os; print(os.environ),检查PATH、PYTHONPATH等关键变量是否存在差异。
4. 改用循环接收逻辑
网络数据可能分批次到达,或传感器响应存在波动,用循环接收确保获取完整数据:
snd = s.send(b'\x00\x0dget_sensor_info') received = b'' while True: chunk = s.recv(1024) if not chunk: break received += chunk # 若传感器返回有固定结束标识(如特定字符序列),可在此处判断并提前终止循环 print(received)
5. 排查安全模块限制
部分Linux系统的SELinux或AppArmor可能对脚本执行的网络操作做了限制,而CLI交互模式不受影响。可临时关闭SELinux测试:
sudo setenforce 0
若脚本恢复正常,需为该脚本添加对应的SELinux规则,避免长期关闭安全模块。
内容的提问来源于stack exchange,提问作者castaway2000

