簡體   English   中英

python停止多線程回顯服務器

[英]python stop multithreaded echo server

我試圖創建多線程回顯服務器:

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(((

echoserver.py:

#!/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提出的線程,但是恕我直言,您還應該實現正確的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()時至少有一個連接處於活動狀態,則在接受超時結束時,只會得到Server is closing... 然后,對於每個連接,它將在收到數據包后立即終止,並由echoserver加入。 然后,當所有連接都結束時,您將Server is closed並且echoserver線程將終止

  • 這意味着在您的主線程中,您只需要做

     serv.stop() serv.join() 

確保所有其他線程均已正確終止,並且所有套接字均已關閉

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM