书上代码如下:
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
天蓬老师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里定义了具体的实现