2016-11-08 86 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,另一個使用不帶。並適當地使用它們。因此,您要做的主要工作是區分通知(不需要響應)和請求(需要響應)。就是這樣。

相關問題