python停止多线程echo服务器

python停止多线程echo服务器,python,multithreading,Python,Multithreading,我尝试创建多线程echo服务器: echomain.py: #!/usr/bin/python from echoserver import echoserver server = echoserver() print server.isRunning() print server.port() server.start() print "Main program continues..."\\This part is not displayed((( #!/usr/bin/python

我尝试创建多线程echo服务器:

echomain.py:

#!/usr/bin/python
from echoserver import echoserver 
server = echoserver()

print server.isRunning()
print server.port()
server.start()
print "Main program continues..."\\This part is not displayed(((
#!/usr/bin/python
import threading
import socket

class connection(threading.Thread):
    def __init__(self, sock, addr):
        self.sock = sock
        self.addr = addr
        threading.Thread.__init__(self)
    def run (self):
        while True:
            buffer = self.sock.recv(1024)
            if buffer == "disconnect\r\n":
                self.sock.send("bye")
                break
            elif buffer:
                self.sock.send(buffer)
        self.sock.close()

class echoserver(object):
    def __init__(self, port=12119):
        self.running = False
        self._port = port
        self._socket = None

    def isRunning(self):
        return self.running

    def port(self):
        return self._port

    def start(self):
        self.running = True
        self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self._socket.bind(("0.0.0.0", self.port()))
        self._socket.listen(5)
        while True:
            conn, addr = self._socket.accept()
            connection(conn, addr).start()

    def stop(self):
        self._socket.close()
        print "Server is closed..." 
echoserver.py:

#!/usr/bin/python
from echoserver import echoserver 
server = echoserver()

print server.isRunning()
print server.port()
server.start()
print "Main program continues..."\\This part is not displayed(((
#!/usr/bin/python
import threading
import socket

class connection(threading.Thread):
    def __init__(self, sock, addr):
        self.sock = sock
        self.addr = addr
        threading.Thread.__init__(self)
    def run (self):
        while True:
            buffer = self.sock.recv(1024)
            if buffer == "disconnect\r\n":
                self.sock.send("bye")
                break
            elif buffer:
                self.sock.send(buffer)
        self.sock.close()

class echoserver(object):
    def __init__(self, port=12119):
        self.running = False
        self._port = port
        self._socket = None

    def isRunning(self):
        return self.running

    def port(self):
        return self._port

    def start(self):
        self.running = True
        self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self._socket.bind(("0.0.0.0", self.port()))
        self._socket.listen(5)
        while True:
            conn, addr = self._socket.accept()
            connection(conn, addr).start()

    def stop(self):
        self._socket.close()
        print "Server is closed..." 

有人能帮助我如何以线程的形式启动echoserver类,使其与主程序同时运行,从而使用echomain.py部分中的stop()方法停止它吗?

将运行程序更改为以线程的形式运行服务器:

echomain.py

#!/usr/bin/python
from echoserver import echoserver
from threading import Thread
import time
server = echoserver()

print server.isRunning()
print server.port()
# server.start()
# run server in a different thread
serverThread = Thread(target=server.start)
serverThread.start()
print "main - server started"
# wait ten seconds before stopping
time.sleep(10)
server.stop()
print "main - server stopped"
print "Main program continues..."

本例仅在10秒后停止服务器。

最简单的方法是让echoserver本身成为Reut Sharabani建议的线程,但是IMHO,您还应该实现正确的stop()方法,确保所有子线程都已结束

以下是我对您的脚本的实现:

#!/usr/bin/python
import threading
import socket

class connection(threading.Thread):
    def __init__(self, sock, addr, parent):
        self.sock = sock
        self.addr = addr
        self.parent = parent
        threading.Thread.__init__(self)
        self.sock.settimeout(None)
        self.closed = False # will be set to True on thread end
    def run (self):
        while not self.parent._stopped:
            buffer = self.sock.recv(1024)
            if buffer == "disconnected\r\n":
                self.sock.send("bye")
                break
            elif buffer:
                self.sock.send(buffer)
        self.sock.close()
        self.closed = True

class echoserver(threading.Thread):
    def __init__(self, port=12119):
        threading.Thread.__init__(self)
        self.running = False
        self._port = port
        self._socket = None
        self._stopped = False
        self._conns = [] # list of active connections

    def isRunning(self):
        return self.running

    def port(self):
        return self._port

    def run(self):
        self.running = True
        self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self._socket.bind(("0.0.0.0", self.port()))
        self._socket.listen(5)
        self._socket.settimeout(5) # use a timeout to respond to stop()
        while not self._stopped:
            try:
                conn, addr = self._socket.accept()
                c = connection(conn, addr, self)
                self._conns.append(c) # add child the the list
                c.start()
            except Exception as e:
                # print e # in debug
                pass
            self._conns = self.child_list() # remove closed child from list
        self._socket.close()
        print "Server is closing..."
        for connect in self._conns: # join active children
            connect.join()
        print "Server is closed"           

    def stop(self):
        self._stopped = True

    def child_list(self):
        l = []
        for conn in self._conns:
            if conn.closed:
                conn.join()
            else:
                l.append(conn)
        return l
备注:

  • 您只需这样使用它:

    serv=echoserver()
    serv.start()
    ... # sleep of do anything you want
    serv.stop()
    
  • 如果在调用stop()时没有连接处于活动状态,则所有连接都将在接受超时结束时停止,您将获得:

    Server is closing...
    Server is closed
    
  • 如果在调用stop()时至少有一个连接处于活动状态,则在接受超时结束时,您只会看到服务器正在关闭…。然后,对于每个连接,它将在收到数据包后立即结束,并将由echoserver加入。然后,当所有连接都结束时,您将看到服务器关闭,echoserver线程将终止

  • 这意味着在主线程中,您只需执行以下操作

    serv.stop()
    serv.join()
    
确保所有其他线程正确终止,并且所有套接字都已关闭