您的位置:首页 > 编程语言 > Python开发

Python3之源码解读socketserver工作流程

2018-01-24 18:06 681 查看

基于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


@整个流程分析结束@!!!

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  socketserver