python - Python 2.7 脚本在调试模式下使用断点,但在运行时不使用
问题描述
def mp_worker(row):
ip = row[0]
ip_address = ip
tcp_port = 2112
buffer_size = 1024
# Read the reset message sent from the sign when a new connection is established
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
print('Connecting to terminal: {0}'.format(ip_address))
s.connect((ip_address, tcp_port))
#Putting a breakpoint on this call in debug makes the script work
s.send(":08a8RV;")
#data = recv_timeout(s)
data = s.recv(buffer_size)
strip = data.split("$", 1)[-1].rstrip()
strip = strip[:-1]
print(strip)
termStat = [ip_address, strip]
terminals.append(termStat)
except Exception as exc:
print("Exception connecting to: " + ip_address)
print(exc)
上面的代码是导致问题的脚本部分。这是一个非常简单的函数,它根据从 DB 查询中传入的 IP 连接到套接字,并接收指示硬件固件版本的响应。
现在,问题是当我在套接字上使用断点在调试中运行它时,我会从硬件获得整个预期的响应,但是如果我在那里没有断点或者我完全运行脚本,它只会响应预期消息的一部分。我尝试在发送之后放置一个 time.sleep() 以查看它是否会获得整个响应,并且我尝试在其中使用注释掉的 recv_timeout() 方法,该方法使用非阻塞套接字和超时来尝试获取整个响应,都具有完全相同的结果。
另请注意,这在一个脚本中工作,所有内容都在一个主代码块中,但我需要将此部分分成一个函数,以便我可以将它与多处理库一起使用。我尝试在本地 Windows 7 机器和 Unix 服务器上运行它,结果相同。
解决方案
我将扩展并重申我刚才发表的评论。我仍然不完全确定这两种情况下不同行为背后的原因(除了时间猜测显然被尝试包含sleep
.
但是,这有点无关紧要,因为流套接字不能保证您一次获得所有请求的数据,并且按请求分块获得。这是由应用程序处理的。如果服务器在发送完整响应后关闭套接字,您可以替换:
data = s.recv(buffer_size)
在recv()
接收到零字节之前,这相当于从系统调用中获取0
( ):EOF
data = ''
while True:
received = s.recv(buffer_size)
if len(received) == 0:
break
data += received
如果不是这种情况,您将不得不依靠您想要一起考虑的固定或已知(在开始时发送)大小。或在协议级别处理此问题(查找用于表示消息边界的字符、序列。
推荐阅读
- go - Overlayfs 复制创建一个空文件
- google-apps-script - 谷歌分享链接到带有选项的工作表
- android - 我无法将 Firestore 文档的值分配给类实例
- python - 我可以使用robot.api 获取失败的测试用例名称吗?
- conda - 如何在 conda 包中设置环境变量,以便在激活包含该包的环境时设置它们?
- java - 将字符串数组列表拆分为其原始字符串元素
- python - Scipy solve_ivp vs odeint
- docker - 连接到独立 chrome 调试容器时如何避免身份验证?
- postgresql - 在 postgresql 中查询多个 Jsonb 列
- point - 将边界框[(x1,y1),(x2,y2),(x3,y3),(x4,y4)] 内的点(x,y) 转换为航向