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

书上代码如下:

一个基于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讲师

répondre à tous(1)
Peter_Zhu

Vous utilisez Python3.5 ?
La relation successorale est

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

Autrement dit, BaseRequestHandler est la classe parent supérieure et la logique de traitement est exécutée par TCPServer, qui est BaseServer.
La logique de traitement principale se trouve dans la fonction serve_forever dans socketserver.py,

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

Regardez à nouveau _handle_request_noblock, ici

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

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

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal