Python:Socket:处理蜂窝网络上的 TCP 连接

发布于 2024-11-16 07:03:35 字数 495 浏览 7 评论 0原文

我正在用 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)

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

写给空气的情书 2024-11-23 07:03:35

如果它是单个设备,您应该使用一个为您处理低级 socket 交互的解决方案... python 有几个类似 pexpect, exscript,或 paramiko(仅限 ssh) ...如果是多个设备并且您需要异步通信,请使用@zeekay的答案(尽管异步编程,特别是扭曲的,如果您还不熟悉的话会令人不快)。

回答了一个问题,并向单个设备发送命令列表......

我用 telnet 的方式 pexpect/5602629#5602629">在 pexpect 中捕获死亡进程

上面的答案使代码变得高效,但对于初学者来说理解起来更具挑战性......下面的代码更简单,它使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 地址时,连接将会断开。

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.

酒中人 2024-11-23 07:03:35

使用网络库,例如 twistedzeromq

Use a networking library like twisted or zeromq.

绅士风度i 2024-11-23 07:03:35

您必须在循环内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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文