Python:非阻塞套接字或异步 I/O

发布于 2024-11-15 16:01:08 字数 973 浏览 0 评论 0原文

我是 Python 新手,目前必须编写一个 Python 套接字作为脚本运行,通过 TCP/IP(气象站)与设备进行通信。
设备充当服务器端(通过IP:PORT监听、接受连接、接收请求、传输数据)。
我只需要发送一条消息,接收答案,然后平静地、很好地关闭并关闭套接字。

try:
    comSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error, msg:
    sys.stderr.write("[ERROR] %s\n" % msg[1])
    sys.exit(1)

try:
   comSocket.connect((''))
except socket.error, msg:
   sys.stderr.write("[ERROR] %s\n" % msg[1])
   sys.exit(2)

comSocket.send('\r')
comSocket.recv(128)
comSocket.send('\r')
comSocket.recv(128)
comSocket.send('\r\r')
comSocket.recv(128)

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

rawData = comSocket.recv(512)

comSocket.shutdown(1)
comSocket.close()

我遇到的问题是:
通信通道不可靠,设备速度慢。因此,有时设备响应长度为 0 的消息(只是一个 ACK​​),我的代码将冻结并永远等待响应。
这段代码包含涉及 SOCKET 的部分,整个代码将在 CRON 下运行,因此冻结不是一个理想的行为。

我的问题是:
Python 中处理这种行为的最佳方法是什么,这样代码就不会冻结并永远等待,而是尝试继续进行下一次发送(或类似的操作)。

I am new to Python and currently have to write a python socket to be run as a script that communicates with a device over TCP/IP (a weather station).
The device acts as the Server Side (listening over IP:PORT, accepting connection, receiving request, transferring data).
I only need to send one message, receive the answer and then peacefully and nicely shutdown and close the socket.

try:
    comSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error, msg:
    sys.stderr.write("[ERROR] %s\n" % msg[1])
    sys.exit(1)

try:
   comSocket.connect((''))
except socket.error, msg:
   sys.stderr.write("[ERROR] %s\n" % msg[1])
   sys.exit(2)

comSocket.send('\r')
comSocket.recv(128)
comSocket.send('\r')
comSocket.recv(128)
comSocket.send('\r\r')
comSocket.recv(128)

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

rawData = comSocket.recv(512)

comSocket.shutdown(1)
comSocket.close()

The problem I'm having is:
The communication channel is unreliable, the device is slow. So, sometimes the device response with message of length 0 (just an ACK), the my code will freeze and wait for response forever.
This piece of code contains the portion that involves SOCKET, the whole code will be run under CRON so freezing is not a desirable behavior.

My question is:
What would be the best way in Python to handle that behavior, so that the code doesn't freeze and wait forever but will attempt to move on to the next send (or such).

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

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

发布评论

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

评论(3

享受孤独 2024-11-22 16:01:08

您可以尝试超时方法,例如 Russel 代码,也可以使用非阻塞套接字,如下面的代码所示。它永远不会在 socket.recv 处阻塞,您可以在循环中使用它来重试任意多次。这样你的程序就不会在超时时挂起。这样,您可以测试数据是否可用,如果不可用,您可以执行其他操作并稍后重试。

socket.setblocking(0)
while (retry_condition):
    try:
        data = socket.recv(512)
    except socket.error:
        '''no data yet..'''

You can try a timeout approach, like Russel code or you can use a non-blocking socket, as shown in the code below. It will never block at socket.recv and you can use it inside a loop to retry as many times you want. This way your program will not hang at timeout. This way, you can test if data is available and if not, you can do other things and try again later.

socket.setblocking(0)
while (retry_condition):
    try:
        data = socket.recv(512)
    except socket.error:
        '''no data yet..'''
愿与i 2024-11-22 16:01:08

我为此推荐 eventlet 和绿色线程。

Twisted 是一个很好的库,但对于这样一个简单的用例来说,学习曲线有点陡峭。

请在此处查看一些示例。

I'd recommend eventlet and green threads for this.

Twisted is a good library but a little steep learning curve for such a simple use case.

Check out some examples here.

葬花如无物 2024-11-22 16:01:08

在接收之前尝试在套接字上设置超时:

comSocket.settimeout(5.0)
try:
    rawData = comSocket.recv(512)
except socket.timeout:
    print "No response from server"

Try, before receiving, putting a timeout on the socket:

comSocket.settimeout(5.0)
try:
    rawData = comSocket.recv(512)
except socket.timeout:
    print "No response from server"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文