3

我正在用 python 进行一些套接字编程,在其中我开发了一个客户端 TCP/IP 套接字来与慢速嵌入式设备进行通信。所以有时,当响应应该只有一个包时,它被分成两个包。我目前的解决方案是sleep()python 程序,等待确保我需要的所有数据都已经到达。

comSocket.send('\r')

sleep(1)

comSocket.send('\r')

comSocket.recv(128)

comSocket.send('\r\r')

comSocket.recv(256)



#sending I commands for data

comSocket.send('1I\r\r3I\r\r4I\r\r13I\r\r5I\r\r8I\r\r7I\r\r9I\r\r')

sleep(2)

#receiving data

rawData = comSocket.recv(512)

sleep(1.5)

我想知道是否有更好的方法来处理这种情况?

4

3 回答 3

1

使用像twistedzeromq这样的网络库。

于 2011-06-21T17:40:36.840 回答
1

如果是单个设备,您应该使用为您处理低级socket交互的解决方案... python 有几个 like pexpectexscriptparamiko(仅限 ssh) ... 如果它是多个设备并且您需要异步通信,使用@zeekay 的答案(虽然异步编程,特别是扭曲的,如果你还不熟悉它,是不愉快的)。

我用你 telnet 的方式回答了一个问题,并将命令列表发送到这里的单个设备......

在预期中捕捉到一个垂死的过程

上面的答案使代码高效,但对于初学者来说更难理解……下面的代码更简单,它在 TCP/23 上建立一个 telnet 连接,等待*,发送一个命令,并将响应放入命令在mydata1...

import pexpect as px
import sys

def send_this(child, retcode, COMMAND):
    if retcode == 2:
        child.sendline(COMMAND)
    else:
        raise RuntimeError, "Could not complete login, due to socket error"

def expect_this(child, EXPR, timeout = 10):
    return child.expect([px.TIMEOUT, px.EOF, EXPR], timeout = timeout)

HOST = '192.168.49.49'
CMD1 = '1I'
PROMPT = '\*'     #Note: you might not need the backslash
TIMEOUT = 10

child = px.spawn('telnet %s' % HOST)
retcode = expect_this(child, PROMPT)
send_this(child, retcode, CMD1)
retcode = expect_this(child, PROMPT)
mydata1 = child.before    # mydata has the output from CMD1

不管解决方案如何,最重要的是调整超时,这样您就不必担心长时间的蜂窝网络延迟(根据我的经验,有时会超过 5 秒)。

蜂窝通信中的另一个令人讨厌的动态是,许多消费者设备在移动时会定期更改其 IP 地址(由于它们对 dhcp 的依赖)......如果发生这种情况,TCP 无能为力......如果你不这样做' t 具有静态地址,当设备提取新的 IP 地址时,连接将断开。

于 2011-06-21T17:55:36.367 回答
0

您必须recv进入一个循环,并且必须检查协议解析器是否已收到所有消息。

condition = True
while condition:
    rawData += sock.recv(512)
    # parse rawData to check if message is complete and if so you can set condition = False to break the loop
    if parser.is_complete(rawData):
        condition = False
于 2011-06-21T17:43:47.183 回答