自学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()     #循环并等待其停止

  在上述实例代码中,自定义一个继承自 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()

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值