Maison > Questions et réponses > le corps du texte
书上代码如下:
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
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里定义了具体的实现