0

同じプロセスで別のモジュールから情報を取得し、それをクライアントに書き戻す asyncore サーバーを作成しています。情報は基本的に、キーごとにメッセージのキューを持つ辞書です。各キューの長さをダンプする必要があります。コードはテスト マシンでは問題なく動作しますが、実稼働サーバーにインストールするとすぐに次のエラー メッセージが表示され始めます: "socket.error'>:[Errno 32] Broken pipe)"。

これはサーバーです:

class request_handler (asyncore.dispatcher):
    def __init__(self, conn_sock, client_address, dict):
            self.client_address  = client_address
            self.buffer = ""
            self.dict = dict
            asyncore.dispatcher.__init__(self, conn_sock)

    def readable(self):
            return True

    def writable(self):
            return False

    def handle_read(self):
            data = self.recv(SIZE)
            mtats = "msgq-stats"

            if data:
                    buffer = data
                    if buffer.lower() == mstats.lower():
                            msgout = "-- Message Queue Stats --\n"
                            for key, value in dict.items():
                                    mq = 0
                                    if dict[key].message_queue:
                                            mq = len(dict[key].message_queue)
                                    msgout += key + ":" + str(mq) + "\n"
                            self.send(msgout)
                    else:   self.send("Invalid input\n")
            else:
                    self.send("Invalid input\n")

    def handle_write(self):
            print ("--Handling read--\n")

    def handle_close(self):
            pass

# ---------------------------------------------------------------------

class monitor_server (asyncore.dispatcher):
    def __init__ (self, ip, port, destination):
            sys.path.append('/path/')
            import dict

            self.ip = ip
            self.port = port
            self.dict = dict
            asyncore.dispatcher.__init__ (self)
            self.create_socket (socket.AF_INET, socket.SOCK_STREAM)

            self.set_reuse_addr()
            self.bind ((ip, port))
            self.listen (5)

    def writable (self):
            return 0

    def handle_read (self):
            pass

    def readable (self):
            return self.accepting

    def handle_connect (self):
            pass

    def handle_accept (self):
             (conn_sock, client_address) = self.accept()
             request_handler (conn_sock, client_address, self.destination)

これはクライアントコードです:

class Client(asyncore.dispatcher_with_send):
   def __init__(self, host, port, message):
      asyncore.dispatcher.__init__(self)
      self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
      self.connect((host, port))
      print "Message being sent is "
      print message
      self.out_buffer = message

  def handle_close(self):
      self.close()

  def handle_read(self):
      print self.recv(1024)
      self.close()

 c = Client('', 6000, 'msgq-stats')
 asyncore.loop()

前もって感謝します。

4

1 に答える 1

0

それはあなたが処理しなければならないエラーケースです。接続が閉じられることがあります。本番環境と比較して、開発中にさまざまなソケットエラーが発生するのは正常です。これは、考えられるさまざまなエラーが非常に多く、それらは実行環境と、接続の反対側のプログラムが何をしているのか、何をしているのかにほぼ完全に依存しているためです。クライアントとサーバー間のすべてのルーターが決定します。

したがって、あなたの質問に対する文字通りの答えは、アプリケーション コードでこのソケット エラーや他の多くのソケット エラーを処理する必要があるということです。これは、asyncore を使用するときの仕事の一部です。必要な例外処理を追加し、このようなことが発生した場合に接続を閉じたものとしてマークします。

もう少し良い答えは、ネットワーク プログラミングを簡単にする高レベルのツールがあり、おそらくそれらの使用を検討する必要があるということです。この分野で重要なのはTwistedです。

于 2013-02-07T00:13:52.170 に答える