2011-12-19 23 views
0

クライアントとの接続が確立されるたびに新しい接続スレッドを作成します。しかし、2回目にクライアントスクリプトを実行すると、エラーが発生します。どのように来るのですか?再帰的接続スレッドの作成

クライアント

from multiprocessing.connection import Client 
conn = Client(('localhost', 5555), authkey='secret_password') 
conn.send('Hello World!') 
conn.close() 

import time 
from multiprocessing.connection import Listener 
from threading import Thread 

_threads = [] 
_listener = Listener(('localhost', 5555), authkey='secret_password') 

def start_server_thread(): 
    global _threads 
    _threads.append(Thread(target=threaded_server)) 
    _threads[-1].daemon = True 
    _threads[-1].start() 

def threaded_server(): 
    conn = _listener.accept() 
    print str(conn.recv()) 
    conn.close() 
    _listener.close() 

if __name__ == "__main__": 
    start_server_thread() 
    while True: 
     time.sleep(1) 

エラー

Traceback (most recent call last): 
    File "C:\dev\spyker\t2.py", line 3, in <module> 
    conn = Client(('localhost', 5555), authkey='secret_password') 
    File "C:\Python26\lib\multiprocessing\connection.py", line 143, in Client 
    c = SocketClient(address) 
    File "C:\Python26\lib\multiprocessing\connection.py", line 263, in SocketClient 
    s.connect(address) 
    File "<string>", line 1, in connect 
socket.error: [Errno 10061] No connection could be made because the target machine actively refused it 

答えて

2

は、このサーバーのコードでいくつかの問題を抱えています。あなたはより多くの接続

import time 
from multiprocessing.connection import Listener 
from threading import Thread 

_threads = [] 

def start_server_thread(): 
    global _threads 
    _threads.append(Thread(target=threaded_server)) 
    _threads[-1].daemon = True 
    _threads[-1].start() 

def threaded_server(): 
    while True: 
     conn = _listener.accept() 
     print str(conn.recv()) 
     conn.close() 


if __name__ == "__main__": 
    _listener = Listener(('localhost', 5555), authkey='secret_password') 

    start_server_thread() 
    while True: 
     time.sleep(1) 

    _listener.close() 

免責のためにループアレント最初の接続

後にリスナーを閉じている

:私は、サーバーを書くための厄介な方法の一種であると思います。私はあなたの現在のコードの修正を投稿しているだけです:-)

ここでは、あなたの同じコードのややきれいなバージョンです。それでも100%理想的ではないが、私はクリーナーだと思う?

import time 
from multiprocessing.connection import Listener 
from threading import Thread 

class Server(Listener): 

    def __init__(self, *args, **kwargs): 
     super(Server, self).__init__(*args, **kwargs) 
     self._thread = None 
     self._stopping = False 


    def serve(self): 
     self._stopping = False 
     self._thread = Thread(target=self._serve) 
     self._thread.daemon = True 
     self._thread.start() 

    def _serve(self): 
     threads = [] 
     while not self._stopping: 
      conn = self.accept() 
      t = Thread(target=self.handleConnection, args=(conn,)) 
      t.start() 
      threads.append(t) 


    def stop(self): 
     if not self._stopping: 
      print "Stopping." 
      self._stopping = True 
      self._thread.join(3) 
      self.close() 

    def handleConnection(self, conn): 
     print str(conn.recv()) 
     conn.close()   


if __name__ == "__main__": 
    listener = Server(('localhost', 5555), authkey='secret_password') 
    listener.serve() 

    try: 
     while True: 
      time.sleep(1) 
    except KeyboardInterrupt, e: 
     listener.stop() 
+0

あなたは正しいです。私の主な問題は、リスナーを閉じて、新しい接続を受け入れることをループしなかったことです。 – Jonathan

+0

@Jonathan - スレッドループハンドラに接続を渡す方法を示す2番目の例を更新したので、サーバーループdoesntブロック – jdi

2

いくつかのエラーが発見サーバー:

  • threaded_serverに無限ループがあり、複数の接続を受け入れることをお勧めします。今は最初のものだけを受け入れています。
  • 処理が終了した後にリスナーを終了しています。これはおそらくあなたが望むものではありません。同じリスナーを使用してさらに多くの接続を受け入れることができます。

正しいthreaded_server():

def threaded_server(): 
    while True: 
     conn = _listener.accept() 
     print str(conn.recv()) 
     conn.close() 
+0

が表示されます。私の主な問題は、リスナーを閉じて、新しい接続を受け入れることをループしなかったことです。 – Jonathan

0

他の回答のアドバイスを使用して修正されたコード。修正された行には、

import time 
from multiprocessing.connection import Listener 
from threading import Thread 

_threads = [] 
_listener = Listener(('localhost', 5555), authkey='secret_password') 

def start_server_thread(): 
    global _threads 
    _threads.append(Thread(target=threaded_server)) 
    _threads[-1].daemon = True 
    _threads[-1].start() 

def threaded_server(): 
    conn = _listener.accept() 
    start_server_thread()   # <== each connection creates the next one 
    print str(conn.recv()) 
    conn.close() 
            # <== removed _listener.close() 
if __name__ == "__main__": 
    start_server_thread() 
    try:       # <== 
     while True: 
      time.sleep(1) 
    except KeyboardInterrupt, e: # <== catch ^c 
     _listener.close()   # <== 
+0

違う。なぜあなたは各スレッドに再帰的に新しいスレッドを作成させていますか?これまでに示した例は正しいですが、whileループを使用して各接続を処理しています。各接続にイベントループが必要な場合は、接続を受け入れてスレッドを生成する単一のサーバーループのみを持つ必要があります。サーバーを再帰的に呼び出さない – jdi

+0

私は、スレッド内のハンドラに各接続を渡す方法を示すために、私の答えで2番目の例を更新しました。 – jdi

+0

@jdi - 接続は非常に長く、新しく並行して接続。わかりやすくするため、1回の受信への接続を減らしました。したがって、whileループは助けにならないでしょう、私は接続ごとに別のスレッドが必要なので、お互いをブロックしません。 – Jonathan

関連する問題