• socketserver模块使用方法


    一、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:break
    10             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)    # 实例化对象,实现多线程的socket
    15     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                 raise
    14 
    15 class BaseServer:
    16     def __init__(self, server_address, RequestHandlerClass):  #(接收了两个传进来的参数)
    17         """Constructor.  May be extended, do not override."""
    18         self.server_address = server_address
    19         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             return
    18         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                 raise
    27         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

    五、调用流程图

  • 相关阅读:
    微信小程序加密解密 C# 以及 填充无效,无法被移除错误的解决方案 Padding is invalid and cannot be removed
    腾讯云 docker 镜像 dotnet/core sdk aspnet
    ImageMagick PDF到JPG有时会导致黑色背景
    VS2019 发布单文件
    MySQL 更新语句执行过程 WAL redolog binlog
    MySQL 查询语句执行过程
    让MySQL为我们记录执行流程
    SQL基础随记1 SQL分类 常用函数 ALL ANY EXISTS IN 约束
    初用MySQL Mysql示例库 Navicat15
    OldTrafford after 102 days
  • 原文地址:https://www.cnblogs.com/eric_yi/p/7701381.html
Copyright © 2020-2023  润新知