????????socketserver模块是标准库中的一个高级模块,它能够简化很多代码,帮我们处理一些繁琐的工作并使用类来编写应用程序。
socketserver模块类 | TCP/UDPServer | 基础的网络同步TCP/UDP服务器 | UnixStreamServer UnixDatagramServer | 基于文件的基础同步TCP/UDP服务器 | ForkingMixIn ThreadingMixIn | 核心派出或线程功能:只用作mix-in类与一个服务器类配合实现一些异步特性,不能直接实例化这个类 | ForkingTCPServer ForkingUDPServer | ForkingMixIn与TCP/UDPServer的结合 | ThreadingTCPServer ThreadingUDPServer | ThreadingMixIn与TCP/UDPServer的结合 | StreamRequestHandler DatagramRequestHandler | 实现TCP/UDP服务器的服务处理器 |
????????与socket模块编写的服务器循环不同,使用socketserver模块编写的服务器循环是事件驱动的,这意味着新的循环不会一直处于阻塞状态,只有在系统的事件发生时它才会工作。要实现服务,必须从StreamRequestHandler或DatagramRequestHandler中选择一个进行实例化并重新定义其中的handle()方法,然后可以通过将其中一个服务器类与请求处理程序类相结合来运行各种版本的服务。
服务器对象
fileno() | 返回服务器正在侦听的套接字的整数文件描述符???????? | server_forever(interval=0.5) | 一直处理请求直到有明确的shutdown()请求,轮询每个interval秒关闭 | setup() | 在handle()方法执行任何初始化操作之前调用,默认状态下不执行任何操作 | handle() | 必须能完成服务器请求所需的全部工作,默认状态下同样不执行任何操作,需要手动修改 其中有几个实例可供调用
self.request | 对流服务这是一个套接字对象,对数据报服务,这是一对字符串和套接字 | self.client_address | 客户地址 | self.server | 服务器实例 | | finish() | 在handle()执行所需清理操作的方法后调用,默认状态下不执行任何操作 |
? ? ? ? 一个简单的TCP服务器
from socketserver import(TCPServer as TCP,StreamRequestHandler as SRH)
HOST=''
PORT=17025
ADDR=(HOST,PORT)
class SHandler(SRH):
def handle(self):
print('connect from:',self.client_address)
self.wfile.write(('do you mean %s ?' %(self.rfile.readline()).decode().strip()).encode())#self.rfile和self.wfile属性可以被读取或写入,以此获得请求的数据或者将数据返回给客户端
tcps=TCP(ADDR,SHandler)
print('waiting for connection...')
tcps.serve_forever()
? ? ? ? 当接收到一个来自客户端的消息时,服务器就会调用handle()方法。StreamRequestHandler类将输入和输出看作类似文件的对象,因此用readline()来获取客户端消息,并利用write()将字符串写入wfile后发送给客户端
????????相较于服务器,客户端没有太大的改变,只是发送格式需要针对服务器的读取形式做出相应改变
from socket import *
HOST='localhost'
PORT=17025
BUUFSIZE=1024
ADDR=(HOST,PORT)
while True:
tcpc=socket(AF_INET,SOCK_STREAM)
tcpc.connect(ADDR)
data=input('>')
if not data:
break
tcpc.send(('%s\r\n' % data).encode())
data=tcpc.recv(BUUFSIZE)
print(data.decode('utf-8').strip())
? ? ? ?运行结果:
?
|