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 相关文章推荐
python将html转成PDF的实现代码(包含中文)
Mar 04 Python
python实现人人网登录示例分享
Jan 19 Python
Python编程中对super函数的正确理解和用法解析
Jul 02 Python
Python+OpenCV人脸检测原理及示例详解
Oct 19 Python
Python实现动态图解析、合成与倒放
Jan 18 Python
python+pyqt5实现24点小游戏
Jan 24 Python
python机器学习库scikit-learn:SVR的基本应用
Jun 26 Python
Python字符串处理的8招秘籍(小结)
Aug 13 Python
python实现的生成word文档功能示例
Aug 23 Python
Python3自动生成MySQL数据字典的markdown文本的实现
May 07 Python
详解python定时简单爬取网页新闻存入数据库并发送邮件
Nov 27 Python
Python如何使用循环结构和分支结构
Apr 13 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和js交互一例-PHP教程,PHP应用
2007/01/03 PHP
php+mysql开源XNA 聚合程序发布 下载
2007/07/13 PHP
php 从一个数组中随机的取出若干个不同的数实例
2016/12/31 PHP
PHP调用全国天气预报数据接口查询天气示例
2019/02/20 PHP
jQuery 技巧小结
2010/04/02 Javascript
javascript中处理时间戳为日期格式的方法
2014/01/02 Javascript
jquery搜索框效果实现方法
2015/01/16 Javascript
javascript中mouseover、mouseout使用详解
2015/07/19 Javascript
javascript实现简单的页面右下角提示信息框
2015/07/31 Javascript
Javascript的表单验证长度
2016/03/16 Javascript
快速使用node.js进行web开发详解
2017/04/26 Javascript
Node.js对MongoDB数据库实现模糊查询的方法
2017/05/03 Javascript
简述vue路由打开一个新的窗口的方法
2018/11/29 Javascript
JavaScript学习笔记之图片库案例分析
2019/01/08 Javascript
详解JavaScript的数据类型以及数据类型的转换
2019/04/20 Javascript
Vue内部渲染视图的方法
2019/09/02 Javascript
如何通过JS实现转码与解码
2020/02/21 Javascript
js实现浏览器打印功能的示例代码
2020/07/15 Javascript
基于Vant UI框架实现时间段选择器
2020/12/24 Javascript
vue-resource 拦截器interceptors使用详解
2021/01/18 Vue.js
python的三目运算符和not in运算符使用示例
2014/03/03 Python
python实现定时同步本机与北京时间的方法
2015/03/24 Python
tensorflow入门之训练简单的神经网络方法
2018/02/26 Python
Python中文件的读取和写入操作
2018/04/27 Python
在python带权重的列表中随机取值的方法
2019/01/23 Python
使用Django xadmin 实现修改时间选择器为不可输入状态
2020/03/30 Python
python使用列表的最佳方案
2020/08/12 Python
HTML5 Canvas图像模糊完美解决办法
2018/02/06 HTML / CSS
HTML5 Canvas 起步(2) - 路径
2009/05/12 HTML / CSS
巴西化妆品商店:Lojas Rede
2019/07/26 全球购物
大学毕业后的十年规划
2014/01/07 职场文书
档案接收函
2014/01/13 职场文书
小学生倡议书范文
2014/05/13 职场文书
设计专业自荐信
2014/06/19 职场文书
会议开幕致辞怎么写
2016/03/03 职场文书
spring注解 @PropertySource配置数据源全流程
2022/03/25 Java/Android