1

3秒間何も受信されない場合にメッセージを出力する単純なサーバーを実装しています。

ハンドラ

class SingleTCPHandler(SocketServer.StreamRequestHandler):
    def handle(self):
        while True:
            message = self.rfile.readline().strip()
            print message

サーバ

class SimpleServer(SocketServer.TCPServer):
    timeout = 3

    def handle_timeout(self):
        print "Timeout"

    def __init__(self, server_address, RequestHandlerClass):
        SocketServer.TCPServer.__init__(self, server_address, RequestHandlerClass)

TCPServerここでは、タイムアウト メソッドをテストするために を拡張しています。に属性を設定しtimeoutました3。ドキュメントによると、その時間が経過し、クライアントにメッセージが送信されないhandle_timeout()場合、私の場合は「タイムアウト」と表示されます。

BaseServer.timeout

秒単位で測定されるタイムアウト時間、またはタイムアウトが必要ない場合は None。handle_request() がタイムアウト期間内に着信要求を受信しない場合、handle_timeout() メソッドが呼び出されます。

サーバーを起動し、出力を観察します。それに接続してメッセージを送信すると、通常は印刷されます。ただし、3 秒以上何も送信しないと何も起こりません。timeoutandhandle_timeout()が実装されていないかのように。

この動作の原因は何ですか?

4

5 に答える 5

4

アプリ ループに対して server_forever() メソッドを呼び出さないでください。代わりにこれを試してください:

while True:
  self.handle_request()

handle_timeout() は私のために働きます。

于 2013-10-14T23:38:05.663 に答える
3

でタイムアウトを宣言してみてくださいself.timeout(つまり、クラス変数ではなくインスタンスフィールドにしますか?)

編集(ここにコードがあります)

def handle_request(self):
           """Handle one request, possibly blocking.

          Respects self.timeout.
          """
          # Support people who used socket.settimeout() to escape
          # handle_request before self.timeout was available.
          timeout = self.socket.gettimeout()
          if timeout is None:
               timeout = self.timeout
           elif self.timeout is not None:
               timeout = min(timeout, self.timeout)
           fd_sets = select.select([self], [], [], timeout)
           if not fd_sets[0]:
               self.handle_timeout()
               return
           self._handle_request_noblock()
于 2013-03-29T15:18:35.500 に答える
2

serve_forever()のドキュメントは次のとおりです。

明示的な shutdown() リクエストまでリクエストを処理します。poll_interval 秒ごとにシャットダウンをポーリングします。self.timeout を無視します。定期的なタスクを実行する必要がある場合は、別のスレッドで実行してください

したがって、は、デフォルト値が 0.5 秒ごとに呼び出されるserve_forever()かどうかのみをチェックします。そして、気にするだけです。shutdown()poll_intervalhandle_request()timeout

serve_forever()handle_request( )のコードは次のとおりです。

于 2015-01-07T23:43:20.103 に答える
1

まず第一に、「3 秒間何も受信されない場合、[サーバー] はメッセージを出力する必要がある」とはどういう意味ですか?

サーバーは...

  1. 特定の期間に新しいリクエストがなかった場合はシャットダウンしますか?
  2. 一定時間内に終了しない場合、接続を閉じますか?

最初のケースでは を使用できますが、代わりにBaseServer.timeoutを使用する必要もあります。BaseServer.handle_request()BaseServer.server_forever()

2 番目のケースでは、次のタイムアウトを設定する必要がありますSingleTCPHandler

class SingleTCPHandler(SocketServer.StreamRequestHandler):
    timeout = 3
    def handle(self):
        while True:
            message = self.rfile.readline().strip()
            print message

の独自の実装を使用したい人向けBaseRequestHandler:

class MyRequestHandler(SocketServer.BaseRequestHandler):
    def handle(self):
        self.request.settimeout(3)
于 2015-02-02T17:44:26.383 に答える
1

最後に、モジュールを削除し、タイムアウトが機能socketserverするモジュールを直接使用しました。socket

TIMEOUT = 3
HOST = '192.0.0.202'              
PORT = 2000             

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
s.listen(1)

while 1:
    conn, addr = s.accept()
    conn.settimeout(TIMEOUT)
    while 1:
        try:
            data = conn.recv(1024)
            #Do things

        except socket.timeout:
            #Timeout occurred, do things

        if not data or P=='end':
            print 'Connection lost. Listening for a new controller.' 
            break

conn.close()
于 2013-05-08T07:48:36.673 に答える