Python 2.7脚本在调试模式下可与断点一起使用,但在运行时则无法使用

时间:2018-06-26 19:03:22

标签: python python-2.7 sockets

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)

上面的代码是导致问题的脚本部分。这是一个非常简单的函数,它根据数据库查询中传入的IP连接到套接字,并接收指示硬件固件版本的响应。

现在,问题是,当我在套接字上带有断点的调试中运行它时,我会从硬件中获得整个预期的响应,但是如果我那里没有断点,或者我已完全运行该脚本,仅用部分预期的消息响应。我尝试将两个time.sleep()放在发送之后,看它是否会获得整个响应,然后尝试在其中使用注释掉的recv_timeout()方法,该方法使用非阻塞套接字和超时来尝试获取一个整个响应,两者的结果完全相同。

请注意,这在脚本中起作用,所有内容都在一个主代码块中,但是我需要将此部分分成一个函数,以便可以在多处理库中使用它。我尝试在本地Windows 7计算机和Unix服务器上运行它,结果相同。

2 个答案:

答案 0 :(得分:1)

我将扩大并重申我刚才发表评论的内容。我仍然不完全确定这两种情况下的不同行为背后是什么(除了时间猜测显然被试图包含sleep所证实。

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

data = s.recv(buffer_size)

使用recv()直到收到零字节为止,这等效于从syscall中获取0EOF):

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

如果不是这种情况,则必须依靠您要一起考虑的固定或已知(开始时发送)的大小。或在协议级别进行处理(查找字符,用于发信号边界的序列。

答案 1 :(得分:0)

我最近在这里找到了一个解决方案,并以为可以将其发布,以防万一其他人遇到问题,我决定先尝试先调用socket.recv(),然后再调用socket.send(),然后再调用socket。之后再次调用recv(),似乎已经解决了该问题;我真的不能告诉你为什么它起作用。

data = s.recv(buffer_size)

s.send(":08a8RV;")

data = s.recv(buffer_size)