开发者

Python: Socket: Handling TCP connections over a cell network

I am doing some socket programming in python in which I develop a client TCP/IP socket to communicate with a slow embedded device. So sometimes, when the response is supposed to be only one package, it is broken in to two packages. My current solution to that is to sleep() the python program, waiting to make sure that all the data 开发者_开发技巧I need already arrived.

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)

I am wondering whether there is a better way to handle this situation?


If it is a single device, you should use a solution that handles the low-level socket interactions for you... python has several like pexpect, exscript, or paramiko (ssh only)... if it is multiple devices and you need asynchronous communication, use @zeekay's answer (although async programming, particularly with twisted, is unpleasant if you're not already familiar with it).

I answered a question with the way you telnet and send a list of commands to a single device here...

Catching a dying process in pexpect

The answer above makes the code efficient, but is more challenging for a beginner to understand... the following code is simpler, it makes a telnet connection on TCP/23, waits for *, sends a command, and puts the response to the command in 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

Regardless of the solution, the most important thing is tweaking your timeouts so you don't have to concern yourself with the long cell-network delays (which are sometimes over 5 seconds in my experience).

The other nasty dynamic in cellular communication is that many consumer devices routinely change their IP address when they are moving (due to their reliance on dhcp)... there isn't much TCP can do if this happens... if you don't have a static address the connection will drop when the device pulls a new ip address.


Use a networking library like twisted or zeromq.


You have to recv inside a loop and will have to check if all message has been received with a protocol parser..

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜