2016-11-08 60 views
1

我正在与一个只支持基本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

可能取决于您的操作系统,但是'select'模块可能适合您? – thebjorn

回答

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很清晰。类似named tuples可能是一个很好的折衷方案 - 您可以初始化一个数据结构中的所有内容,同时仍然使用已命名的字段进行清晰。

0

我已经使用类似的程序,并在一个我使用if messagemessage在这种情况下是从套接字接收的字符串。这里是我的代码:

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 
2

如果您不知道回复是否应该先发送邮件,那么您注定要失败。让我重复一遍:如果API或者不响应,你不知道什么时候它是游戏结束。那是因为这个问题“我应该等待回应吗?”无法回答。与Python完全无关,切换语言无法解决这个问题。但是这样的API会非常糟糕。许多有用的工具(例如超时,并发访问)将不可能实现(或非常困难)。

另一方面,如果您确实知道API应该何时响应,何时不响应,那么就像创建两个函数一样简单:一个使用recv,另一个使用不带。并适当地使用它们。因此,您要做的主要工作是区分通知(不需要响应)和请求(需要响应)。就是这样。