我正在与一块硬件进行通信,该硬件只有一个支持基本API调用的基本API。
不幸的是,一些API调用违反了响应,有些则没有。我想在有一个时读取响应,或者在没有响应时不做任何操作。
以下是我一直在使用的代码:
def send_message(self, message, host):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((host, self.PORT))
s.send(bytes(message, 'ascii'))
data = s.recv(1024)
print(data)
不幸的是,当没有收到数据时,这会绑定整个过程。我只想在有实际响应时读取数据。有没有办法用Python标准库做到这一点?
答案 0 :(得分:2)
首先,如果您可以控制目标API,我建议为每条消息实施回复。对于发送的每条消息,回复ACK(确认)将使您的API更加健壮,并完全回避此问题。
如果那不是一个选项,那么我会为不同类型的消息创建类:
class Message(object):
def __init__(self, msg):
self.msg = msg
class MessageWReply(Message):
await_reply = True
class MessageNoReply(Message):
await_reply = False
创建所有邮件类,然后像这样使用它们:
def send_message(self, message, host):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((host, self.PORT))
s.send(bytes(message, 'ascii'))
if message.await_reply:
data = s.recv(1024)
print(data)
或者,如果您不想要创建所有类的开销,可以使用字典将消息映射到正确的操作:
messages = {
'message with reply 1': True, # wait for reply
'message with reply 2': True,
'message with reply 2': True,
'message without reply 1': False, # don't wait for reply
'message without reply 2': False
}
然后这样做:
def send_message(self, message, host):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((host, self.PORT))
s.send(bytes(message, 'ascii'))
if messages[message]:
data = s.recv(1024)
print(data)
第二种方法具有更清晰的初始化(更少的样板代码),但有点不太明确。对于不熟悉代码的人,不清楚messages[message]
存储的值实际意味着什么,而message.await_reply
非常明确。像{{3}}这样的东西可能是一个很好的折衷方案 - 您可以在一个数据结构中初始化所有内容,同时为了清晰起见仍使用命名字段。
答案 1 :(得分:2)
如果您不知道响应是否应该先于发送消息,那么您注定要失败。让我再说一遍:如果API响应与否,你不知道什么时候它会结束游戏。那是因为问题“我应该等待回应吗?”是无法回答的。它完全与Python无关,切换语言无助于解决这个问题。但是这样的API会非常糟糕。许多有用的工具(例如超时,并发访问)是不可能(或非常难)实现的。
另一方面,如果您确实知道API应该何时响应,那么它就像创建两个函数一样简单:一个具有recv
而另一个没有。并适当地使用它们。因此,您需要做的主要工作是区分通知(不需要响应)和请求(需要响应)。就是这样。
答案 2 :(得分:0)
我使用过类似的程序,在我使用if message
的{{1}}中,message
在这种情况下是从套接字接收的字符串。这是我的代码:
while True:
readbuffer = readbuffer + s.recv(1024)
temp = string.split(readbuffer, "\n")
readbuffer = temp.pop()
for line in temp:
try:
user = getUser(line)
message = getMessage(line)
except IndexError:
print "Nothing to receive from the server!"
if message:
#responses here