博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
socketserver模块使用方法
阅读量:5975 次
发布时间:2019-06-20

本文共 4645 字,大约阅读时间需要 15 分钟。

一、socketserver模块介绍

Python提供了两个基本的socket模块。一个是socket,它提供了标准的BSD Socket API; 另一个是socketserver,它提供了服务器中心类,可以简化网络服务器的开发

  socketserver

socketserver内部使用IO多路复用以及“多线程”和“多进程”,从而实现并发处理多个客户端请求的socket服务端。 即,每个客服端请求连接到服务器时,socket服务端都会在服务器上创建一个“线程”或“进程”专门负责处理当前客户端的所有请求。

 

二、socketserver中的ThreadingTCPServer类

ThreadingTCPServer实现的socket服务器内部会为每个client创建一个“线程”,该线程用来和客户端就行交互 ThreadingTCPServer源码内容:

class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass#可以看到ThreadTCPServer类本身并没有方法,而是继承了(ThreadingMinIn, TCPServer) 这两个类。 而TCPServer则是继承了BaseServer类。

 

三、ThreadingTCPServer的使用方法

1、创建一个继承socketserver.BaseRequestHandler的类

2、类中必须重写一个名为handler的方法

3、实例化一个服务器类,传入服务器的地址和请求处理程序类

4、调用serve_forever()事件循环监听

1 #!/usr/bin/env python3 2 import socketserver 3  4 class Handler(socketserver.BaseRequestHandler):    # 必须继承BaseRequestHandler 5     def handle(self):        # 必须有handle方法 6         print('New connection:',self.client_address) 7         while True: 8             data = self.request.recv(1024) 9             if not data:break10             print('Client data:',data.decode())11             self.request.send(data)12 13 if __name__ == '__main__':14     server = socketserver.ThreadingTCPServer(('127.0.0.1',8009),Handler)    # 实例化对象,实现多线程的socket15     server.serve_forever()    # 事件监听,并调用handler方法
View Code

 

四、ThreadingTCPServer执行过程

1、启动服务端程序

2、执行TCPServer.__init__方法,创建服务端socket对象并绑定IP和端口(根据类的继承关系,即查找顺序找到TCPServer.__init__())

3、执行BaseServer.__init__方法,将自定义的继承自socketserver.BaseRequestHandler的类MyRequestHandler赋值给self.RequestHandlerClass class TCPServer(BaseServer): #(继承了BaseServeer类)

1 class TCPServer(BaseServer): #(继承了BaseServeer类) 2     def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True): 3         """Constructor.  May be extended, do not override.""" 4         BaseServer.__init__(self, server_address, RequestHandlerClass)  #(重写了BaseServer的__init__方法) 5         self.socket = socket.socket(self.address_family, 6                                     self.socket_type) 7         if bind_and_activate: 8             try: 9                 self.server_bind()10                 self.server_activate()11             except:12                 self.server_close()13                 raise14 15 class BaseServer:16     def __init__(self, server_address, RequestHandlerClass):  #(接收了两个传进来的参数)17         """Constructor.  May be extended, do not override."""18         self.server_address = server_address19         self.RequestHandlerClass = RequestHandlerClass     #(赋值给了self.RequestHandlerClass)20         self.__is_shut_down = threading.Event()21         self.__shutdown_request = False
View Code

4、通过实例化的对象,执行serve_forever方法,该方法首先查找到BaseServer下的方法,通过调用selector模块,注册事件监听对象,并执行_handle_request_noblock方法 找到此方法,并调用该方法下的process_request方法,在此调用到finish_request方法,通过finish_request方法,执行了RequestHandlerClass方法,执行此方法就相当于调用 了我们重写的Handler类。

1 class BaseServer: 2     def serve_forever(self, poll_interval=0.5): 3         try: 4             with _ServerSelector() as selector: 5                 selector.register(self, selectors.EVENT_READ) 6  7                 while not self.__shutdown_request: 8                     ready = selector.select(poll_interval) 9                     if ready:10                         self._handle_request_noblock()11 12                     self.service_actions()13    def _handle_request_noblock(self):14         try:15             request, client_address = self.get_request()16         except OSError:17             return18         if self.verify_request(request, client_address):19             try:20                 self.process_request(request, client_address)21             except Exception:22                 self.handle_error(request, client_address)23                 self.shutdown_request(request)24             except:25                 self.shutdown_request(request)26                 raise27         else:28             self.shutdown_request(request)29     def process_request(self, request, client_address):30         self.finish_request(request, client_address)31         self.shutdown_request(request)32     def finish_request(self, request, client_address):33         self.RequestHandlerClass(request, client_address, self)
View Code

5、通过Handler类实例化对象,调用继承的BaseRequestHandler类中的__init__方法,并执行了handler方法。 从而运行了我们重写Handler类中的handler方法。

class BaseRequestHandler:    def __init__(self, request, client_address, server):        self.request = request        self.client_address = client_address        self.server = server        self.setup()        try:            self.handle()   #调用handler()        finally:            self.finish()
View Code

 

五、调用流程图

转载于:https://www.cnblogs.com/eric_yi/p/7701381.html

你可能感兴趣的文章
memcpy的使用方法总结
查看>>
内部类的应用
查看>>
JSP网站开发基础总结《六》
查看>>
poj2955Brackets(区间DP)
查看>>
Atitit.数据索引 的种类以及原理实现机制 索引常用的存储结构
查看>>
LeetCode: Surrounded Regions [130]
查看>>
java web mvc思想介绍
查看>>
Spring 一二事(8) - annotation 形式的 MVC
查看>>
hdu1010 dfs+路径剪枝
查看>>
K-th Number(第k大数)
查看>>
关于curl: (2) Failed Initialization
查看>>
Non-negative Partial Sums(单调队列)
查看>>
Android EditText禁止复制粘贴
查看>>
STM8不用手动复位进入自带Bootloader方法(串口下载)
查看>>
Unable to extract 64-bitimage. Run Process Explorer from a writeable directory
查看>>
如何使用ODBC搭配dsn链接数据库
查看>>
android 官方DrawerLayout的介绍和使用
查看>>
mysql错误用法insert into where
查看>>
openwrt l7过滤qos配置
查看>>
dns
查看>>