Python探索之SocketServer详解


Posted in Python onOctober 28, 2017

SocketServer,网络通信服务器,是Python标准库中的一个模块,其作用是创建网络服务器。SocketServer模块定义了一些类来处理诸如TCP、UDP、UNIX流和UNIX数据报之上的同步网络请求。

SocketServer模块处理网络请求的功能,可以通过两个主要的类来实现:一个是服务器类,一个是请求处理类。
服务器类 处理通信问题,如监听一个套接字并接收连接等;

请求处理类 处理“协议”问题,如解释到来的数据、处理数据并把数据发回给客户端等。

这种实现将服务器的实现过程和请求处理的实现过程解耦,这意味着我们可以将不同的服务器实现和请求处理实现结合起来来处理一些定制的协议,例如一个TCP服务器类和一个流请求处理类结合,处理基于TCP的网络请求。同时,也可以基于SocketServer模块中的服务器类和请求处理类,实现网络层之上应用层的服务器和请求处理实现,例如基于TCP服务器类实现HTTP服务器,基于流处理请求类实现HTTP请求处理类等。

服务器类

SocketServer模块中定义了五种服务器类。
BaseServer(服务器的基类,定义了API)
TCPServer(使用TCP/IP套接字)
UDPServer(使用数据报套接字)
UnixStreamServer(使用UNIX域套接字,只适用UNIX平台)
UnixDatagramServer(使用UNIX域套接字,只适用UNIX平台)

1. 构造服务器对象

要构建一个服务器对象,需要向它传递一个地址server_address(服务器将在这个地址上监听请求),以及一个请求处理类RequestHandlerClass(不是请求处理实例)。服务器类基类的构造函数如下:

class 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
 

后,可以构造TCPServer、UDPServer、UnixStreamServer、UnixDatagramServer。其中,TCPServer继承自BaseServer,UDPServer和UnixStreamServer继承自TCPServer,UnixDatagramServer继承自UDPServer。各个服务器类型可以根据自己的特点对基类进行扩展,例如创建监听套接字、绑定监听地址和端口、进行监听等。一旦实例化服务器对象,便可以使用服务器的方法来监听和处理请求。

2. 实现服务器

由于SocketServer模块中定义的五种服务器类中,除了基类BaseServer和TCPServer外,其余的三个类都是直接或间接地继承自TCPServer。因此,以下以TCPServer的实现过程为例进行说明。

构造TCPServer。 构造TCPServer时,构造函数创建了一个套接字(这个套接字可以通过更改地址簇和类型用于其他服务器)用于监听请求。并且调用server_bind()绑定监听的地址和端口,调用server_activate()开始监听。

启动服务器。 服务器实例化后,可以使用serve_forever()或者handle_request()来监听和处理请求,实现服务器功能。这两个方法的具体实现依赖于_handle_request_noblock()方法。这个方法是BaseServer类中定义的。具体实现如下:

def _handle_request_noblock(self):
 """Handle one request, without blocking.
 I assume that select.select has returned that the socket is
 readable before this function was called, so there should be
 no risk of blocking in get_request().
 """
 try:
  request, client_address = self.get_request()
 except socket.error:
  return
 if self.verify_request(request, client_address):
  try:
   self.process_request(request, client_address)
  except:
   self.handle_error(request, client_address)
   self.shutdown_request(request)
 else:
  self.shutdown_request(request)

处理请求。 根据上一步骤启动服务器后,服务器便开始监听请求。如果接收到请求信息,便开始处理请求。由_handle_request_noblock()可以看出有几个函数比较重要。

get_request() ——这个函数可以在子类中重写。在TCPServer中,该函数调用监听套接字的accept()方法,返回请求request和客户端地址client_address。

verify_request(request, client_address) ——这个函数可以在子类中重写。该函数返回True表示处理请求,返回False表示忽略请求。

process_request(request, client_address) ——这个函数可以在子类中重写。该函数将调用finish_request()具体完成请求的处理过程,并且在处理完请求后关闭请求。

finish_request(request, client_address) ——该函数将构造一个请求处理类的实例。请求处理类被实例化后将调用其handle()方法处理请求。

3. 进程/线程支持

SocketServer模块中还提供了一些”mix-in”类:ForkingMixIn和ThreadingMixIn。这些类可以和服务器类混合使用,很容易改变服务器,为每个请求使用一个单独的进程或线程。具体的服务器类有:

class ForkingUDPServer(ForkingMixIn, UDPServer)
class ForkingTCPServer(ForkingMixIn, TCPServer)
class ThreadingUDPServer(ThreadingMixIn, UDPServer)
class ThreadingTCPServer(ThreadingMixIn, TCPServer)
class ThreadingUnixStreamServer(ThreadingMixIn, UnixStreamServer)
class ThreadingUnixDatagramServer(ThreadingMixIn, UnixDatagramServer)

请求处理类

要接收到来的请求以及确定采取什么行动,其中大部分的工作都是由请求处理类完成的。请求处理类负责在套接字层之上实现协议。具体过程为:读取请求、处理请求、写回响应。请求处理类基类中定义了3个方法,子类中需要重写。

setup() ——为请求准备请求处理器
handle() ——对请求完成具体的工作。诸如解析到来的请求,处理数据,并发回响应等。
finish() ——清理setup()期间创建的所有数据

总结

以上就是本文关于Python探索之SocketServer详解的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站:Python探索之URL Dispatcher实例详解、Bottle框架中的装饰器类和描述符应用详解等,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

Python 相关文章推荐
windows下python模拟鼠标点击和键盘输示例
Feb 28 Python
python获取本地计算机名字的方法
Apr 29 Python
浅谈python类属性的访问、设置和删除方法
Jul 25 Python
TensorFlow安装及jupyter notebook配置方法
Sep 08 Python
浅谈Django学习migrate和makemigrations的差别
Jan 18 Python
pandas中apply和transform方法的性能比较及区别介绍
Oct 30 Python
Python re 模块findall() 函数返回值展现方式解析
Aug 09 Python
Python类如何定义私有变量
Feb 03 Python
Django+boostrap 美化admin后台的操作
Mar 11 Python
python实现简单的五子棋游戏
Sep 01 Python
自己搭建resnet18网络并加载torchvision自带权重的操作
May 13 Python
Python Flask请求扩展与中间件相关知识总结
Jun 11 Python
Bottle框架中的装饰器类和描述符应用详解
Oct 28 #Python
Pandas探索之高性能函数eval和query解析
Oct 28 #Python
Python探索之URL Dispatcher实例详解
Oct 28 #Python
Python探索之Metaclass初步了解
Oct 28 #Python
Python编程之Re模块下的函数介绍
Oct 28 #Python
Python探索之静态方法和类方法的区别详解
Oct 27 #Python
Python探索之爬取电商售卖信息代码示例
Oct 27 #Python
You might like
PHP文本操作类
2006/11/25 PHP
php+mysqli数据库连接的两种方式
2015/01/28 PHP
PHP设计模式之装饰器模式定义与用法详解
2018/04/02 PHP
php 中htmlentities导致中文无法查询问题
2018/09/10 PHP
PHP面向对象程序设计模拟一般面向对象语言中的方法重载(overload)示例
2019/06/13 PHP
关于laravel后台模板laravel-admin select框的使用详解
2019/10/03 PHP
向fckeditor编辑器插入指定代码的方法
2007/05/25 Javascript
javascript 页面划词搜索JS
2009/09/28 Javascript
JavaScript高级程序设计 阅读笔记(十四) js继承机制的实现
2012/08/14 Javascript
js使浏览器窗口最大化实现代码(适用于IE)
2013/08/07 Javascript
jQuery的观察者模式详解
2014/12/22 Javascript
Node.js实现Excel转JSON
2015/04/24 Javascript
jQuery通过Ajax返回JSON数据
2015/04/28 Javascript
javaScript数组迭代方法详解
2016/04/14 Javascript
IOS中safari下的select下拉菜单文字过长不换行的解决方法
2016/09/26 Javascript
浅谈JavaScript事件绑定的常用方法及其优缺点分析
2016/11/01 Javascript
微信小程序基于本地缓存实现点赞功能的方法
2017/12/18 Javascript
JS实现图片上传多次上传同一张不生效的处理方法
2018/08/06 Javascript
微信{"errcode":48001,"errmsg":"api unauthorized, hints: [ req_id: 1QoCla0699ns81 ]"}
2018/10/12 Javascript
在Vant的基础上封装下拉日期控件的代码示例
2018/12/05 Javascript
详解Puppeteer前端自动化测试实践
2019/02/21 Javascript
vue登录页面cookie的使用及页面跳转代码
2019/07/10 Javascript
[07:37]DOTA2-DPC中国联赛2月2日Recap集锦
2021/03/11 DOTA
python线程池的实现实例
2013/11/18 Python
Python获取Linux系统下的本机IP地址代码分享
2014/11/07 Python
下载python中Crypto库报错:ModuleNotFoundError: No module named ‘Crypto’的解决
2018/04/23 Python
对python中基于tcp协议的通信(数据传输)实例讲解
2019/07/22 Python
在Python中等距取出一个数组其中n个数的实现方式
2019/11/27 Python
Python实现CNN的多通道输入实例
2020/01/17 Python
对Matlab中共轭、转置和共轭装置的区别说明
2020/05/11 Python
MxNet预训练模型到Pytorch模型的转换方式
2020/05/25 Python
Python 爬虫批量爬取网页图片保存到本地的实现代码
2020/12/24 Python
css3动画 小球滚动 js控制动画暂停
2019/11/29 HTML / CSS
彪马日本官网:PUMA日本
2019/01/31 全球购物
促销活动计划书
2014/05/02 职场文书
导游词之鲁迅祖居
2019/10/17 职场文书