创建递归连接线程

时间:2011-12-19 18:16:23

标签: python listener multiprocessing

每次与客户端建立连接时,我都会创建一个新的连接线程。但是,在第二次运行客户端脚本时,我收到错误,怎么回事?

客户

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

3 个答案:

答案 0 :(得分:2)

发现了一些错误:

  • 您可能希望您的threaded_server具有无限循环并接受多个连接。现在它只接受第一个而且存在。
  • 处理结束后你正在关闭监听器,这可能不是你想要的。您可以使用相同的侦听器接受更多连接。

更正threaded_server():

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

答案 1 :(得分: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()

答案 2 :(得分: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()         # <==