我正在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)
我想知道是否有更好的方法来处理这种情况?
答案 0 :(得分:1)
答案 1 :(得分:1)
如果它是单个设备,您应该使用一个处理低级socket
交互的解决方案... python有几个像pexpect
,exscript或{ {3}} ...如果它是多个设备并且您需要异步通信,请使用@ 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可以做如果发生这种情况......如果您没有静态地址,则当设备提取新的IP地址时连接将丢失。
答案 2 :(得分: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