我的查询是关于我已经将树莓派作为服务器而我需要通过另一个使用套接字的设备来控制pi的gpio。我的服务器代码就是当我发送字符串' on&#39时通过客户端,LED必须开启,关闭,闪烁,然后通过客户端关闭。尽管led开/关/闪烁都是成功的,但我在led闪烁期间面临问题。如果客户端在LED闪烁操作期间打开/关闭字符串,那么led的开/关操作是不成功的。那我该怎么做呢? 任何帮助表示赞赏。
# server code
import socket
import time
import sys
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BOARD)
GPIO.setup(12,GPIO.OUT)
GPIO.output(12,False)
ms=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
ms.bind(('',1234))
ms.listen(1)
conn,addr=ms.accept()
print('Connection Established from ',addr)
while True:
data=conn.recv(1000)
print(addr,': ',data)
if not data:
break
elif data==b'raspberry\n':
print('Hello Pi')
elif data==b'on\n':
print('led is turned ON')
GPIO.output(12,True)
elif data==b'off\n':
print('led is turned OFF')
GPIO.output(12,False)
elif data==b'blink\n':
print('led blinking')
while True: #.... Here Is my query....
GPIO.output(12,True)
time.sleep(0.5)
GPIO.output(12,False)
time.sleep(0.5)
if conn.recv(1000)==b'on\n' or conn.recv(1000)==b'off\n':
break
elif data==b'exit\n':
print('Goodbye..')
time.sleep(1.5)
break
conn.close()
ms.close()
sys.exit()
答案 0 :(得分:1)
问题是您使用收到的数据,但不将其存储在data
中。
您需要将收到的数据存储在data
:
while True:
GPIO.output(12,True)
time.sleep(0.5)
GPIO.output(12,False)
time.sleep(0.5)
data = conn.recv(1000)
if data==b'on\n' or data==b'off\n':
break
但是,data
将在下一次迭代时被data = conn.recv(1000)
覆盖。
因此,您需要在此时响应开/关指令。
while True:
GPIO.output(12,True)
time.sleep(0.5)
GPIO.output(12,False)
time.sleep(0.5)
data = conn.recv(1000)
if data==b'on\n':
#on
break
elif data==b'off\n':
#off
break
正如您所要求的,这是一种处理网络应用程序的简单方法。
首先,有一个接收消息的线程。
import threading
import queue
class Receiver(threading.Thread):
def __init__(self, connection):
super().__init__()
self.connection = connection
self.messages = queue.Queue()
def run(self):
while True:
message = self.connection.recv(1000)
self.queue.put(message)
def get_message(self):
if not self.queue.empty():
return self.queue.get()
else:
return None
然后,在主循环中,不要等待来自conn
的消息,而是使用Receiver
对象的队列。
receiver = Receiver(conn) # conn is the connection object returned by ms.accept()
receiver.start()
while True:
message = receiver.get_message()
if message is not None:
process_message(message)
好的,所以这里有很多事情,但实际上并不那么难。
首先,我定义了一个Receiver
类,它扩展了threading.Thread
,并覆盖了__init__
和run
。
__init__
方法用于设置允许获取消息的属性,run
方法描述线程将执行的操作。
该线程将运行一个永久while
循环,在该循环中,它将从网络接收消息,并将它们放入队列中。
顺便说一句,queue
模块给出了同步队列,其中包括Queue
。
在线程上下文中使用这些而不是列表是个好主意。
此外,从Queue
对象获取对象并不是那么简单,因此我在get_message
类中定义了Receiver
方法,这将为我完成工作。
然后我通过传递从Receiver
收到的conn
对象来实例化ms.accept
类,然后开始我的线程。
最后,我运行我的主while
循环,在其中我使用来自接收者队列的消息。
那么它有什么变化?
接收方法(此处为conn.recv
)是阻塞的,这意味着它们会停止其线程的执行流程。
通过将它们放在自己的线程中,主线程将不会被暂停。
通过Queue
对象,主线程可以从接收线程获取数据,但不会被阻止。
如果有数据,则需要它。如果没有,它就会继续。