我在这里是一个noob,但试图设置一个脚本,我可以轮询一个套接字,并且当没有套接字数据发送时,循环继续运行并执行其他操作。我一直在玩使用select()发现的几个例子,但不管我如何组织代码,它似乎停止在server.recv()行上或附近,并等待响应。如果客户端没有发送数据,或者没有客户端连接,我想跳过这一点。Python套接字选择正在挂起 - 在等待套接字数据时执行其他任务?
请注意,此应用程序不需要服务器脚本发送任何答复数据,如果它有任何区别。
实际应用是运行一个循环并为一些LED设置动画(需要根访问Raspberry Pi上的I/O)。我将通过套接字从另一个单独的脚本发送此脚本数据,这些套接字将传递动画的控制参数。这样外部脚本不需要root权限。
到目前为止,数据的发送和接收都非常有效,我无法在没有输入数据的情况下获得循环。这是我的理解,这是select()打算允许的,但我发现的例子似乎并没有这样工作。
我试图添加server.setblocking(0)几个不同的地方无济于事。 (如果我理解正确,一个非阻塞实例应该允许代码跳过recv(),如果没有数据已经发送,但我可能会关闭)。
我有我的基础上这里的示例代码: http://ilab.cs.byu.edu/python/select/echoserver.html
这里是服务器端脚本,然后客户端脚本。
服务器代码:sockselectserver.py
#!/usr/bin/env python
import select
import socket
import sys
server = socket.socket()
host = socket.gethostname()
port = 20568
size = 1024
server.bind((host,port))
server.listen(5)
input = [server,sys.stdin]
running = 1
while running:
inputready,outputready,exceptready = select.select(input,[],[])
for s in inputready:
if s == server:
# handle the server socket
client, address = server.accept()
input.append(client)
elif s == sys.stdin:
# handle standard input
junk = sys.stdin.readline()
running = 0
else:
# handle all other sockets
data = s.recv(size)
if data:
s.send(data)
else:
s.close()
input.remove(s)
print "looping"
server.close()
客户端代码:skclient.py
#!/usr/bin/python # This is client.py file
import socket # Import socket module
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 20568 # Reserve a port for your service.
s.connect((host, port))
data = "123:120:230:51:210:120:55:12:35:24"
s.send(data)
print s.recv(1024)
s.close # Close the socket when done
我想什么通过这个例子来实现,就是看 “循环” 重复永远,然后当客户端脚本发送数据时,看到数据打印,然后一遍又一遍地看到“循环”恢复打印。那会告诉我它正在做我打算从那里拿到的东西。
有趣的是,当我按照原样进行测试时,无论何时运行客户端,我都会在屏幕上看到“循环”打印3次,然后就不再显示了。我不完全理解选择内部发生了什么,但我认为它只会打印一次。
我试着将inputready .. select.select()移动到不同的地方,但发现它似乎需要每次调用,否则服务器停止响应(例如,如果它在无尽的while :循环)。
我希望这可以做得很简单,它可以教授制造商类的其他黑客类型,所以我希望我不需要太多疯狂的多线程和更复杂的解决方案。作为最后的手段,我正考虑从外部脚本中将所有参数记录到mySQL,然后使用此脚本将它们从表格中查询回来。我有经验,可能会工作,但似乎这个插座角度将是一个更直接的解决方案。
任何帮助,非常感谢。
服务器必须是它自己的循环imo – YOU
感谢您的快速回复。我不知道我将如何实现这一点。你能分享一个示例代码片段吗?我是否将所有内容都封装在一个循环中?如果是,我会在哪里调用其他函数(那些将被反复调用的函数,仅在客户端发送传入数据时才会中断)? – kjav
尝试使用超时(秒)调用'select.select()'选项:'select.select(input,[],[],1)'。 – acw1668