python中socketserver的一个疑问
PHP中文网
PHP中文网 2017-04-17 17:32:27
0
1
440

书上代码如下:

一个基于sockerserver的小型服务器

from socketserver import TCPServer,StreamRequestHandler

class Handler(StreamRequestHandler):

def handle(self):                  
    print(type(self.request))
    addr = self.request.getpeername()    
    print('Got connection from ',addr)
    self.wfile.write(b'thank you for connecting...')

server = TCPServer(('li-linfeng1',1234),Handler)
server.serve_forever()

我的问题是,Handler中的self.request为什么是一个socket对象呢?

self.request所在的类BaseRequestHandler源代码如下,从源代码中也看不出self.request是socket对象,求问是怎么知道这个self.request是socket对象,从而可以调用getpeername()方法的呢?

class BaseRequestHandler:

"""Base class for request handler classes.

This class is instantiated for each request to be handled.  The
constructor sets the instance variables request, client_address
and server, and then calls the handle() method.  To implement a
specific service, all you need to do is to derive a class which
defines a handle() method.

The handle() method can find the request as self.request, the
client address as self.client_address, and the server (in case it
needs access to per-server information) as self.server.  Since a
separate instance is created for each request, the handle() method
can define arbitrary other instance variariables.

"""

def __init__(self, request, client_address, server):
    self.request = request
    self.client_address = client_address
    self.server = server
    self.setup()
    try:
        self.handle()
    finally:
        self.finish()

def setup(self):
    pass

def handle(self):
    pass

def finish(self):
    pass
PHP中文网
PHP中文网

认证高级PHP讲师

全部回覆(1)
Peter_Zhu

用的Python3.5?
繼承關係是

你自己的handler <-- StreamRequestHandler <---BaseRequestHandler

也就是BaseRequestHandler是最上面的父類,而處理邏輯由TCPServer也就是BaseServer執行。
其主要處理邏輯位於socketserver.py裡的serve_forever函數,

def serve_forever(self, poll_interval=0.5):
        """Handle one request at a time until shutdown.

        Polls for shutdown every poll_interval seconds. Ignores
        self.timeout. If you need to do periodic tasks, do them in
        another thread.
        """
        self.__is_shut_down.clear()
        try:
            # XXX: Consider using another file descriptor or connecting to the
            # socket to wake this up instead of polling. Polling reduces our
            # responsiveness to a shutdown request and wastes cpu at all other
            # times.
            with _ServerSelector() as selector:
                selector.register(self, selectors.EVENT_READ)

                while not self.__shutdown_request:
                    ready = selector.select(poll_interval)
                    if ready:
                        self._handle_request_noblock() # 执行非阻塞的数据读取

                    self.service_actions()
        finally:
            self.__shutdown_request = False
            self.__is_shut_down.set()
        

你再看下_handle_request_noblock,這裡面

        try:
            request, client_address = self.get_request()
        except OSError:
            return
其逻辑就是获取与客户端连接的socket,然后丢给注册的Handler处理

TCPServer里的get_requeset里定义了具体的实现

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板