Python套接字挂起程序

时间:2014-02-17 02:27:55

标签: python sockets

我正在使用Python中的简单HTTP服务器。我从这里获取点点滴滴:http://hg.python.org/cpython/file/3.3/Lib/socketserver.py看看Python的标准库如何处理它。

我的问题是,一旦我尝试接受请求,我的程序就会挂起。这是我的代码只有100行,所以我直接在这里发布。

我有一个process()函数,它在循环中永远循环,并且它假设处理新的连接。在里面我有一个只打印一次的打印声明。

在TCPServer.process()

中打印('处理')

我试过线程关闭process(),但我得到了相同的结果。

"""."""

import socket
import select
from abc import abstractmethod, ABCMeta


class BaseServer(metaclass=ABCMeta):

    def __init__(self, server_address, server_port, RequestHandlerClass):
        self._server_address = server_address
        self._server_port = server_port
        self._RequestHandlerClass = RequestHandlerClass
        self._running = False

    def serve_forever(self):
        self._running = True
        while self._running:
            self.process()

    @abstractmethod
    def process(self):
        pass

    def shutdown(self):
        self._running = False


class TCPServer(BaseServer):

    def __init__(self,
                server_address,
                server_port,
                RequestHandlerClass,
                address_family=socket.AF_INET,
                socket_type=socket.SOCK_STREAM,
                request_queue_size=1,
                bind=True):

        super(TCPServer, self).__init__(server_address,
                                        server_port,
                                        RequestHandlerClass)

        self._address_family = address_family
        self._socket_type = socket_type
        self._request_queue_size = request_queue_size
        self._socket = socket.socket(self._address_family, self._socket_type)
        self._read_list = [self._socket]

        if bind:
            self.bind()

    def bind(self):
        self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self._socket.bind((self._server_address, self._server_port))
        self._socket.listen(self._request_queue_size)

    def shutdown(self):
        super().shutdown()
        self._socket.close()

    def process(self):
        print('processing')
        readable, writeable, errored = select.select(self._read_list, [], [])
        for socket in readable:
            if socket is self._socket:
                client_socket, client_address = self._socket.accept()
                self._read_list.append(client_socket)
                print('connection from: ', client_address)
            else:
                self._RequestHandlerClass(client_socket)
                self._read_list.remove(client_socket)


class BaseRequestHandler(metaclass=ABCMeta):

    def __init__(self, client_socket):
        self._client_socket = client_socket

        self.setup()
        try:
            self.handle()
        finally:
            self.finish()

    @abstractmethod
    def setup(self):
        pass

    @abstractmethod
    def handle(self):
        pass

    @abstractmethod
    def finish(self):
        pass


class HTTPRequestHandler(BaseRequestHandler):

    def setup(self):
        print('REQUEST SETUP')
        print(self._client_socket.recv(2048))

    def handle(self):
        print('REQUEST HANDLE')

    def finish(self):
        print('REQUEST FINISH')
        self._client_socket.close()


if __name__ == '__main__':
    tcp_server = TCPServer(server_address='',
                        server_port=9000,
                        RequestHandlerClass=HTTPRequestHandler)
    tcp_server.serve_forever()

1 个答案:

答案 0 :(得分:3)

我运行了你的代码但却无法挂起。但是,process()函数中存在致命错误,您在client_socket分支中引用了else:,但此时未定义client_socket。你可能想要引用socket

我能够在端口9000上与服务器建立两个连接,并为每个连接获得“连接:”行。只要其中一个连接发送了某些内容,您的服务器就会因上述原因而崩溃。