首页 > 解决方案 > 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 服务器上运行它,结果相同。

标签: pythonpython-2.7sockets

解决方案


我将扩展并重申我刚才发表的评论。我仍然不完全确定这两种情况下不同行为背后的原因(除了时间猜测显然被尝试包含sleep.

但是,这有点无关紧要,因为流套接字不能保证您一次获得所有请求的数据,并且按请求分块获得。这是由应用程序处理的。如果服务器在发送完整响应后关闭套接字,您可以替换:

data = s.recv(buffer_size)

recv()接收到零字节之前,这相当于从系统调用中获取0( ):EOF

data = ''
while True:
    received = s.recv(buffer_size)
    if len(received) == 0:
        break
    data += received

如果不是这种情况,您将不得不依靠您想要一起考虑的固定或已知(在开始时发送)大小。或在协议级别处理此问题(查找用于表示消息边界的字符、序列。


推荐阅读