基于TCP套接字的2种循环分为:通信循环和链接循环
socketserver模块既然用来处理并发,那么分为两大类:
解决链接问题的server类,解决通信问题的request类
server类主要有
:
#处理链路
+------------+
| BaseServer |
+------------+
|
v
+-----------+ +------------------+
| TCPServer |------->| UnixStreamServer |
+-----------+ +------------------+
|
v
+-----------+ +--------------------+
| UDPServer |------->| UnixDatagramServer |
+-----------+ +--------------------+
#处理多线程并发:
"ThreadingMixIn","ThreadingUDPServer","ThreadingTCPServer"
#处理多进程并发:
"ForkingUDPServer","ForkingTCPServer", "ForkingMixIn"
request类主要有
(处理通信循环):
"BaseRequestHandler", "StreamRequestHandler","DatagramRequestHandler"
各类之间的继承关系
:
Let`s roll:
code:
import socketserver
class FtpServer(socketserver.BaseRequestHandler):
def handle(self):
pass
ftpserver = socketserver.ThreadingTCPServer(('127.0.0.1', 8080), FtpServer)
ftpserver.serve_forever()
我们只看TCP协议:
先看下属性的查找顺序:
+--------------------+
| ThreadingTCPServer |
+--------------------+
|
v
+----------------+
| ThreadingMixIn |
+----------------+
|
v
+-----------+
| TCPServer |
+-----------+
|
v
+-----------+
| BaseServer|
+-----------+
实例化得到ftpserver ,执行TCPServer类的__init__方法,并执行 server_bind()
和self.server_activate():
class TCPServer(BaseServer):
def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True):
self.server_bind()
self.server_activate()
找到ftpserver 下的serve_forever,这个方法在BaseServer下,执行self._handle_request_noblock():
class BaseServer:
def serve_forever(self, poll_interval=0.5):
self._handle_request_noblock()
看下self._handle_request_noblock():
def _handle_request_noblock(self):
#相当于TCPServer中的self.socket.accept()
request, client_address = self.get_request()
#接收完请求后处理请求和客户端地址
self.process_request(request, client_address)
这时找到了ThreadingMixIn的process_request方法,执行process_request_thread方法,:
class ThreadingMixIn:
def process_request_thread(self, request, client_address):
self.finish_request(request, client_address)
def process_request(self, request, client_address):
"""开启新线程处理请求"""
t = threading.Thread(target = self.process_request_thread,
args = (request, client_address))
t.daemon = self.daemon_threads
t.start()
到此就完成了链接循环的处理,接着看下通讯循环:
BaseServer中finish_request中:
def finish_request(self, request, client_address):
"""通过实例化类去结束一个请求,实例化一个类触发__init__方法"""
self.RequestHandlerClass(request, client_address, self)
这里找到了BaseRequestHandler
class BaseRequestHandler:
def __init__(self, request, client_address, server):
#调用了对象自己的handle()
self.handle()
class FtpServer(socketserver.BaseRequestHandler):
def handle(self):
pass