Python中的SocketServer模块

Python中的SocketServer模块

socket编程过于底层,编程虽然有套路,但是想要写出健壮的代码还是比较困难的,所以很多语言都对socket底层 API进行封装,Python的封装就是——socketserver模块。它是网络服务编程框架,便于企业级快速开发。

  1. 类的继承关系

    +------------+
    | BaseServer |
    +------------+
        |
        v
    +-----------+        +------------------+
    | TCPServer |------->| UnixStreamServer |
    +-----------+        +------------------+
        |
        v
    +-----------+        +--------------------+
    | UDPServer |------->| UnixDatagramServer |
    +-----------+        +--------------------+
    
  2. SocketServer简化了网络服务器的编写

    • 它有4个同步类:
      1. TCPServer
      2. UDPServer
      3. UnixStreamServer
      4. UnixDatagramServer
    • 两个Mixin类,用来支持异步。
      • ForkingMixIn
      • ThreadingMixIn
    • 组合得到
      • class ForkingUDPServer(ForkingMixIn,UDPServer):pass
      • class ForkingTCPServer(ForkingMixIn,TCPServer):pass
      • class ThreadingUDPServer(ThreadingMixIn,UDPServer):pass
      • class ThreadingTCPServer(ThreadingMixIn,TCPServer):pass
  • fork是创建多进程,thread是创建多线程。
  • fork需要操作系统支持,Windows不支持。
  • ThreadingUDPServer与ThreadingTCPServer类中的特有属性:
    1. daemon_threads=False #默认值是False表示创建的线程都不是daemon线程,改为True表示创建的所有线程都是daemon线程
    2. block_on_close=False #默认值为Fasle,如果为True,可以设置为守护线程3.7版本可以用

编程接口

  1. socketserver.BaseServer(server_address,RequestHandlerClass) #实例化一个服务器

    • server_address #服务器绑定的地址信息,是一个元组(ip,prost)
    • RequestHandlerClass #必须是BaseRequestHandler的一个子类。
    • 在BaseServer中原码代码如下:
    def __init__(self, server_address, RequestHandlerClass):
        """Constructor.  May be extended, do not override."""
        self.server_address = server_address
        self.RequestHandlerClass = RequestHandlerClass
        self.__is_shut_down = threading.Event()
        self.__shutdown_request = False
    
    # 处理请求的方法,会实例化一个RequestHandlerClass对象
    def finish_request(self, request, client_address):
        """Finish one request by instantiating RequestHandlerClass."""
        self.RequestHandlerClass(request, client_address, self)
    
  2. BaseServer中定义的接口常用属性和方法

方法 含义
server_address 服务器正在监听的地址和端口,在不同协议格式不一样。Internet协议上是一个元组(“127.0.0.1”,80)
socket 服务器正在监听的套接字对象。socket
request_queue_size 请求队列的大小。如果处理单个请求需要很长时间,那么在服务器繁忙时到达的任何请求都会被放入队列中,直到request_queue_size请求为止。一旦队列满了,来自客户机的进一步请求将得到一个“连接被拒绝”错误。默认值通常是5,但是可以被子类覆盖。
address_family 服务器套接字所属的协议族。常见的例子是套接字。AF_INET socket.AF_UNIX。
socket_type 服务器使用的套接字类型;套接字。SOCK_STREAM套接字。SOCK_DGRAM是两个常见的值。
timeout 超时持续时间,以秒为单位度量,如果不需要超时,则为None。如果handle_request()在超时期间没有收到传入的请求,则调用handle_timeout()方法。
handle_request() 处理单个请求,同步执行
这个函数按顺序调用以下方法:get_request()、verify_request()和process_request()。如果处理程序类的用户提供的handle()方法引发异常,将调用服务器的handle_error()方法。如果在超时秒内没有收到任何请求,那么将调用handle_timeout()并返回handle_request()。
server_forever(poll_interval=0.5) 异步执行,处理请求。每隔poll_interval秒轮询一次。
忽略timeout属性,还会调用service_actions(),在ForkingMixIn的子类中定义,可以用来清理僵尸进程。
shutdown() 告诉serve_forever循环停止。并等待他结束。
server_close() 关闭服务器
finish_request(request,client_address) 通过实例化RequestHandlerClass并调用它的handle()方法来处理请求
server_bind() 由服务器的构造函数调用,以将套接字绑定到所需的地址。可能会被覆盖。
verify_request(request,client_address) 必须返回一个布尔值;如果值为True,请求将被处理,如果值为False,请求将被拒绝。可以重写此函数来实现服务器的访问控制。默认实现总是返回True。

BaseRequestHandler类

  1. 是和用户连接的用户请求处理类的基类,
  2. BaseRequestHandler(request,client_address,server) #构造函数
    • request #是和客户端的连接的socket对象
    • client_address #是客户端地址
    • server #是TCPServer实例本身
  3. 服务端Server实例接收用户请求后,最后会实例化这个类。它被初始化时,送入3个构造参数:request, client_address, server自身 以后就可以在BaseRequestHandler类的实例上使用以下属性:
    • self.request是和客户端的连接的socket对象
    • self.server是TCPServer实例本身
    • self.client_address是客户端地址
  4. 这个类在初始化的时候,它会依次调用3个方法。子类可以覆盖这些方法。
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()
        finally:
            self.finish()

    def setup(self): #每一个连接初始化
        pass

    def handle(self): #每一次请求处理
        pass

    def finish(self): #每一个连接清理
        pass
  • 测试代码
import socketserver
import socket

class MyBaseRequestHandle(socketserver.BaseRequestHandler):

    def setup(self):
        super().setup
  • 13
    点赞
  • 67
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值