2016-11-08 7 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

はお使いのOSによって異なる場合がありますが、おそらく 'select'モジュールが有効でしょうか? – thebjorn

答えて

2

第1に、ターゲット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) 

第2の方法は、掃除機の初期化(以下定型コード)を有しているが、少しあまり明確ではありません。コードに慣れていない人にとっては、は明瞭であるが、messages[message]に格納されている値が実際にどのような意味を持っているのかははっきりしない。 named tuplesのようなものは良い妥協点かもしれません - 明快にするために名前付きフィールドを使用しながら、すべてのデータ構造を初期化することができます。

0

私も同様のプログラムで作業していましたが、if messageを使用しました。この場合は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 
2

応答がメッセージを送信するために先験的に従わなければならないかどうかわからない場合は、あなたは破棄されます。私は繰り返します:APIが応答するかどうか、それがいつゲームオーバーであるかわからない場合。これは、「回答を待つべきか」という質問があるからです。答えられないそして、Pythonとはまったく無関係です。切り替え言語は、それを解決するのに役立つものではありません。しかし、そのようなAPIは非常に悪いです。多くの有用なツール(タイムアウト、同時アクセスなど)は実装が不可能(または非常に困難)です。

一方、APIが応答するとわかっている場合は、それがない場合は、recvと1つではなく2つの関数を作成するのと同じくらい簡単です。それを適切に使用してください。だから、あなたがしなければならない主な仕事は、(応答を必要としない)の通知と(応答を必要とします)の要求を区別することです。以上です。

関連する問題