search

Home  >  Q&A  >  body text

python中socketserver的一个疑问

书上代码如下:

一个基于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中文网2810 days ago443

reply all(1)I'll reply

  • 天蓬老师

    天蓬老师2017-04-17 17:34:27

    Using Python3.5?
    The inheritance relationship is

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

    That is, BaseRequestHandler is the top parent class, and the processing logic is executed by TCPServer, which is BaseServer.
    The main processing logic is located in the serve_forever function in 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()
            

    Look at _handle_request_noblock again, here

            try:
                request, client_address = self.get_request()
            except OSError:
                return
    其逻辑就是获取与客户端连接的socket,然后丢给注册的Handler处理
    
    TCPServer里的get_requeset里定义了具体的实现
    

    reply
    0
  • Cancelreply