• 自学Python 60 socketserver编程


    Python socketserver 编程



      在Python语言中,提供了高级别的网络服务模块socketserver ,在里面提供了服务器中心类,可以简化网络服务器的开发步骤。本节介绍socketsever对象开发网络程序的知识。


    一、socketserver 模块基础

      socketserver是Python标准库中的一个高级模块,在Python 3以前的版本中被命名为SocketServer,推出socketserver的目的是简化程序代码。在Python程序中,虽然使用前面介绍的socket模块可以创建服务器,但是开发者要对网络连接等进行管理和编程。为了更加方便地创建网络服务器,在Python标准语言库中提供了一个创建网络服务器的模块socketserver。 socketserver框架将处理请求划分为两个部分,分别对应服务器类和请求处理类。服务器类处理通信问题,请求处理类处理数据交换或传送。这样,更加容易进行网络编程和程序的扩展。同时,该模块还支持快速的多线程或多进程的服务器编程。

      在模块socketserver中,包含如下所示的几个基本构成类。
      (1)类socketserver.TCPServer(server_ address,RequestHandlerClas,bind_and_activate=True)
      类 TCPServer是一个基础的网络同步 TCP服务器类,能够使用TCP 协议在客户端和服务器之间提供连续的数据流。如果 bind_and_activate为 true,构造函数将自动尝试调用server_bind()和 server_ activate(),其他参数会被传递到BaseServer基类。

      (2)类socketserver.UDPServer(server_address, RequestHandlerClaass, bind_and_activate=True)
      类 UDPServer是一个基础的网络同步UDP服务器类,实现在传输过程中可能不按顺序到达或丢失时的数据包处理, 参数含义与 TCPServer相同。

      (3)类socketserver.UnixStreamServer(server_address, RequestHandlerClass, bind_and_activate=True) 和 类 socketserver. UnixDatagramServer(server_address, RequestHandlerClass, bind_and_activate=True)
       基于文件的基础同步 TCP/UDP服务器,与前面TCP和UDP类似,但是使用的是Unix域套接字,只能在Unix平台上使用。 参数含义与 TCPServer相同。

      (4)类 BaseServer
      包含核心服务器功能和 mix-in类的钩子;仅用于推导,这样不会创建这个类的实例;可以用 TCPServer 或UDPServer创建类的实例。

      在socketsever中,上述模块构成类的继承关系如下图所示:
    在这里插入图片描述

      除了上述基本的构成类外,在模块socketserver中还包含了其他的功能类,具体说明如下表所示。

    功能
    ForkingMixIn/ThreadingMixIn核心派出或线程功能:只用作mix-in类与一个服务器类配合实现一些异步性;不能直接实例化这个类
    ForkingTCPServer/ForkingUDPServerForkingMixIn和 TCPServer/UDPServer的组合
    ThreadingTCPServer/ThreadingUDPServerThreadingMixIn和 TCPServer/UDPServer的组合
    BaseRequestHandler包含处理服务请求的核心功能:仅仅用于推导,这样无法创建这个类的实例:可以使用StreamRequestHandler或DatagramRequestHandler创建类的实例
    StreamRequestHandler/ DatagramRequestHandler实现 TCP/UDP 服务的处理器

       其中有TCP字符使用的是 TCP协议的服务器类,UDP字符使用UDP协议的服务器类,Threading字符使用的是多线程服务器类, Forking字符使用的是多进程服务器类。 要想创建不同类型的服务器程序,只需继承其中之一或直接实例化,然后调用服务器类方法serve_forever()即可。这些服务器的构造方法参数主要有:

     ● server_address: 由IP地址和端口构成的元组。
     ● RequestHandlerClass: 处理器类,供服务器类调用处理数据。

      在socketserver模块中最为常用的处理器类主要有StreamRequestHandler(基于TCP协议的)和 DatagramRequestHandler (基于UDP协议的)。只要继承其中之一,就可以自定义一个处理器类。通过覆盖以下三个方法可以实现自定义功能。
      (1) setup(): 为请求准备请求处理器(请求处理的初始化工作)
      (2) handle (): 实现具体的请求处理工作(解析请求、处理数据发出响应)。
      (3)finish: 清理请求处理器相关数据。

    二、使用socketserver创建 TCP“客户端/服务器”程序

      在下面的实例文件中,演示了 socketserver建立TCP“客户端/服务器”连接的过程。实例文件 ser.py的功能是使用socketserver 模块创建基于 TCP协议的服务器端程序,具体实现代码如下所示。

    import socketserver
    HOST = ''
    PORT = 10000
    toSend = "你好,客户端,这里是服务端!"  # 设置发送数据
    #定义类 StreamRequestHandle的子类MyTcpHandler
    class MyTcpHandler(socketserver.StreamRequestHandler):
        def handle(self):       #定义函数handle()
            while True:
                data = self.request.recv(1024)      #返回接收到的数据
                if not data:
                    Server.shutdown()       #关闭连接
                    break       #停止循环
                print('服务端接收到的信息:',data.decode('utf-8'))     #显示接收信息
                self.request.send(toSend.encode('utf-8'))     #发送信息
            return
    #定义类TCPserver的对象实例
    Server = socketserver.TCPServer((HOST,PORT),MyTcpHandler)
    Server.serve_forever()     #循环并等待其停止
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

      在上述实例代码中,自定义一个继承自 StreamRequestHandler的外理器类,并覆盖了方法 handler以实现数据处理。然后直接实例化了类 TCPServer,调用方法serve_forever()启动服务器。
      客户端使用的是上一文章中的实例文件jiandankehu.py,本实例的最终执行结果如下所示。
    在这里插入图片描述
    在这里插入图片描述

    三、使用 ThreadingTCPServer创建“客户端/服务器”通信程序

      在 ThreadingTCPServer实现的Soket服务器内部,会为每一个client创建一个“线程”,该线程用来和客户端进行交互。在Python程序中,使用ThreadingTCPServrer的步骤如下所示。

      (1)创建一个继承自 SocketServer.BaseRequestHandler的类。
      (2)必须在类中定义一个名为handle 的方法。
      (3)启动 ThreadingTCPServer。

      例如在下面的实例代码中,演示了使用ThreadingTCPServer创建“客户端/服务器”通信程序的过程。
      实例文件TTser.py的功能是使用socketserver模块创建服务器端程序,能够将收到的信息直接发回到客户端。文件TTser.py的具体实现代码如下所示。

    import socketserver
    class Myserver(socketserver.BaseRequestHandler):
        def handle (self):
            conn = self.request
            conn.sendall(bytes("你好,这里是服务端", encoding="utf-8"))
            while True:
                ret_bytes = conn.recv(1024)
                ret_str = str(ret_bytes,encoding="utf-8")
                if ret_str == "q":
                    break
                conn.sendall(bytes(ret_str + " 你好我好大家好", encoding = "utf-8"))
    if __name__ == "__main__":
        server = socketserver.ThreadingTCPServer(("127.0.0.1",10000) ,Myserver)
        server.serve_forever()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

      客户端依然可以使用上一文章中的实例文件jiandankehu.py。

  • 相关阅读:
    链接脚本(1) --- 在默认的链接脚本中插入段
    spring cloud 快速上手系列 -> 03-消息队列 Stream -> 034-消费消息
    CSRF漏洞详解与挖掘
    VMware安装Debian,Debian分区,虚拟机使用NAT模式联网,Linux设置静态IP
    vmware虚拟机开机之后一直闪烁
    视觉特效,图片转成漫画功能
    spinal HDL - 10 - 状态机
    粒子群算法(主要针对连续型函数优化问题)
    JS提升:Promise中reject与then之间的关系
    05 MIT线性代数-转置,置换,向量空间Transposes, permutations, spaces
  • 原文地址:https://blog.csdn.net/weixin_46066007/article/details/126732825