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/ForkingUDPServer | ForkingMixIn和 TCPServer/UDPServer的组合 |
ThreadingTCPServer/ThreadingUDPServer | ThreadingMixIn和 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。