Python——socketserver

  在Python 2.x中, socketserver模块名为SocketServer。该模块可以简化创建服务器的过程。

  该模块有四个比较主要的类型,其中常用的是 TCPServer 和 UDPServer。

  1. TCPServer

  2. UnixStreamServer,类似于TCPServer提供面向数据流的套接字连接,但是旨在UNIX平台上可用;

  3. UDPServer

  4. UnixDatagramServer,类似于UDPServer提供面向数据报的套接字连接,但是旨在UNIX平台上可用;

这四个类型同步地处理请求,也就是说一个请求没有完成之前是不会处理下一个请求的,这种模式当然不适合生产环境,一个客户端连接就可能拖延所有的执行。所以这个模块还提供了两种支持异步处理的方式: 

  ForkingMixIn,为每一个客户端请求派生一个新的进程去专门处理;

  ThreadingMixIn,为每一个客户端请求派生一个新的线程去专门处理;

  首先从高层面介绍一下使用SocketServer模块开发多进程/线程异步服务器的流程:

  1. 创建一个合适的服务类型,如,面向TCP连接的多进程服务器:  ForkingTCPServer

  2. 创建一个请求处理句柄(request handler)类型,这个类型的 handle() 方法(类似于回调函数)将会处理到达的客户端请求连接。

  3. 实例化服务器,传入服务器应该绑定的地址和处理请求的句柄类

  4. 调用服务器实例的 handle_request() 或 serve_forever() 方法,一次或多次处理客户请求。

1. 构建合适的服务器类型

  上文介绍了SocketServer模块提供的几种主要的基本服务类型和两种MixIn类型,就是构造适合需求的多线程/进程服务器的原料。是否使用、如何使用这两个MixIn类型是由程序员决定的,利用的就是Python的多重继承机制,将MixIn类型作为代码库(而不是初始化实例的工具),为实例提供新的方法。

  比如,定义一个使用TCP连接的线程式异步服务器类型:

class ForkingTCPServer(FrokingMixIn, TCPServer):    pass

  Python的多重继承机制保证了这里只要继承了必要的父类就可以完成目标类型的定义,不需要添加额外的内容。

2. 创建请求处理句柄类

  SocketServer模块提供了 BaseRequestHandler 类型用于定制Handler类型,自定义的Handler类型只要继承自 BaseRequestHandler 并覆写它的 handle() 方法即可。handle() 方法定义如何处理客户端的请求,服务器只是封装了socket对象的众多操作流程以及进程、线程等的管理,然后对于每一个客户端请求调用handle() 方法。

  BaseRequestHandler类型提供如下的接口,他们都可以根据需要覆写:

  (1).  BaseRequestHandler.setup()

  作用:在handle() 方法之前调用,完成一些初始化的工作,默认的情形下什么也不做。

  

  (2).  BaseRequestHandler.handle()

  作用:完成所有的对于每个请求的处理工作,默认情况下什么也不做。该方法可以获取一些实例属性,可以在实现时使用: self.request 是客户端的请求,对于TCP而言,该属性是一个套接字对象,对于UDP而言,该属性是一个由字符串和套接字组成的二元组。 self.client_address 是客户端套接字的地址, self.server 则是服务器实例。

   StreamRequestHandler 和 DatagramRequestHandler 能够屏蔽 self.request 对TCP和UDP连接的区别,二者都重定义了setup()和finish()方法,提供统一的 self.rfile 和 self.wfile 属性以便从客户端读取数据或向客户端发送数据。

  (3).  BaseRequestHandler.finish()

  作用:在handle() 方法之后调用,完成一些清理的工作,默认的情形下什么也不做。如果setup()方法抛出异常,那么该方法不会被调用。

3. 实例化服务器

  实例化服务器时传入服务器需要绑定的地址是必要的,另一方面还应该传入自定义的Handler类型,服务器实例将对每一个客户端连接调用它的 handle() 方法。

  例如:

server = ForkingTCPServer((host, port), MyRequestHandler)

4. 调用服务器实例的处理方法

  服务器实例的 handle_request() 方法与 serve_forever() 方法分别用于单次处理或一直处理请求,可以直接在脚本中调用这些方法,也可以在新的进程或者线程中调用这些方法,启动服务器:

import threading

...

server = ForkingTCPServer((host, port), MyRequestHandler)
server_thread = threading.Thread(target = server.serve_forever)server_thread.start()

补充:

  SocketServer中的TCPServer、UDPServer提供的可供使用的属性、方法(实际上都来自于其父类 SocketServer.BaseServer ):

属性:

BaseServer.address_family

  内容:服务器套接字对象的地址族,如 socket.AF_INET 、 socket.AF_UNIX 等。

BaseServer.RequestHandlerClass

  内容:用户自定义,传给服务器构造函数Handler类型,服务器会为每一个请求创建一个该类型的实例。

BaseServer.server_address

  内容:服务器监听的地址,具体的形式依赖于地址族,如AF_INET形式的 (‘127.0.0.1‘, 80) 等。

BaseServer.socket

  内容:服务器监听的套接字对象

BaseServer.allow_reuse_address

  内容:是否允许地址重用,默认为False,子类可以更改。

BaseServer.request_queue_size

  内容:请求队列的长度,一旦等待服务的请求数达到这个限制,后续到来的请求收到“Connection denied”错误,通常该值默认为5,子类可以覆写。

  

BaseServer.socket_type

  内容:服务器所用套接字的类型,如 socket.SOCK_STREAM 和 socket.SOCK_DGRAM 。

BaseServer.timeout

  内容:服务器的超时限制,如果是None,那么没有设置超时;如果在指定的时限内 handle_request() 方法没有获得请求,那么将会调用 handle_timeout() 方法。

BaseServer.fileno()

  内容:返回服务器所用套接字对象的fd,一种典型的用法是传给 select.select() 方法便于在一个进程中监控多个服务器。

方法:

BaseServer.server_bind()

  作用:由实例的构造函数调用,将套接字绑定到目标地址,可以覆写。

BaseServer.server_activate()

  作用:由实例的构造函数调用,监听服务器套接字,可以覆写。

BaseServer.handle_request()

  作用:处理单个请求,依次调用 get_request() 、 verify_request() 和 process_request() 方法,如果用户自定义的handle()方法抛出异常,则调用 handle_error() 方法,如果超过 self.timeout 秒没有获得请求,调用 handle_timeout() 方法,然后 handle_request() 方法返回。

   BaseServer.get_request()

    作用:服务器对象的使用者不一定需要直接调用该方法,从套接字接受一个请求。返回一个二元组,首元是新的已经连接的套接字对象,次元是客户端的地址。

   BaseServer.verify_request(request, client_address)

    作用:服务器对象的使用者不一定需要直接调用该方法。返回一个布尔值,为True时处理请求,为False时拒绝请求,可以通过覆写该方法为服务器实现访问控制。默认的实现总是返回True。

   BaseServer.process_request(request, client_address)

    作用:该方法体现MixIn的作用,此处可能会创建线程或进程来处理用户的请求,最终都是该方法通过调用 finish_request() 来为每个请求实例化一个用户自定义的Handler实例,然后投到新建的线程或进程中,处理用户的请求。

     BaseServer.finish_request()

      作用:为每个请求实例化一个用户自定义的Handler实例,并调用其 handle() 方法。

   BaseServer.handle_error(request, client_address)

    作用:当用户自定义的Handler实例的 handle() 方法抛出异常时,调用该方法。默认的工作是将traceback打印到标准输出,然后继续处理请求。

   BaseServer.handle_timeout()

    作用:当self.timeout属性规定的超时上限达到时(不是None)还没有等到请求。多进程服务器的默认行为是收集所有已经退出的子进程的状态,多线程服务器默认什么也不做。

BaseServer.serve_forever(poll_interval=0.5)

  作用:一直处理请求,直到显式调用 shutdown() 函数,每隔 poll_interval (默认0.5)秒轮询一遍shutdown,该函数无视 self.timeout 。

BaseServer.shutdown()

  作用:停止 serve_forever() 循环直到其停止。


Contact_me: darren_wang_a^t_outlook.com
时间: 2025-01-15 18:02:07

Python——socketserver的相关文章

使用Python SocketServer快速实现多线程网络服务器

Python SocketServer使用介绍 1.简介:          SocketServer是python的一个网络服务器框架,可以减少开发人员编写网络服务器程序的工作量. SocketServer总共有4个server基类. TCPServer:负责处理TCP协议. UDPServer:负责处理UDP协议. UnixStreamServer:只适用于类unix平台,不常用. UnixDatagramServer:只适用于类unix平台,不常用. 这4个类会同步处理每一个request

python SocketServer

SocketServer是标准库中一个高级别的模块,用于简化网络客户与服务器的实现.模块中,已经实现了一些可供使用的类. 在Python3中,本模块为socketserver模块.在Python 2中,本模块为SocketServer模块.所以在用import导入时,要分情况导入,否则会报错.导入的代码如下: ? 1 2 3 4 try:     import socketserver      #Python 3 except ImportError:     import SocketSer

python SocketServer 框架编程

1. SocketServer框架 在python中,socketserver是一个已集成的模块,它有以下特点: 可用SocketServer框架创建TCP和UDP服务器. 在后台为你做好每一个基础步骤. 可以手动创建一个服务器欺骗客户端和分析它的行为. 2. SocketServer模块的用法 必须是BaseRequestHandler的子类 重写handle()函数 调用handle_request或者serve_forever处理客户端程序. 对TCP 服务端来说 self.request

python SocketServer 源码分析

附上原文链接: http://beginman.cn/python/2015/04/06/python-SocketServer/

python socketserver并发实例

#以下为服务端 improt socketservera class MyTCPHandler(socketserver.BaseRequestHandler): def handle(self): while True: print("New Conn:",self.client_address) data=self.request.recv(1024) if not data:break print ("Client Save:",data.decode())

python socketserver 实现 ftp功能

需求: 用户加密认证 允许同时多用户登录 每个用户有自己的家目录 ,且只能访问自己的家目录 对用户进行磁盘配额,每个用户的可用空间不同 允许用户在ftp server上随意切换目录 允许用户查看当前目录下文件 允许上传和下载文件,保证文件一致性 文件传输过程中显示进度条 附加功能:支持文件的断点续传 client: #coding:utf-8 import socket import json import os #client.connect(('192.168.16.200',9999))

Python——socketserver编程(客户端/服务器)

一.socketserver是标准库中的高级模块,它的目标是简化很多多样板代码,是创建网络客户端和服务器所必须的代码.(事件驱动) 二.模块类 BaseServer :包含核心服务器功能和mix-in类的钩子,可以用TCPServer或UDPserver创建类的实例 TCPserver/UDPserver:基础的TCP/UDP服务器 UnixStereamServer/UnixDatagramServer:基于文件的TCP/UDP服务器 ForkingMixIn/ThreadingMixIn:核

python --- Socketserver N部曲(1)

曲一 socketserver 是为了简化服务器端开发而产生的,是一个高级的标准库.(背景介绍完毕,开始干) 一些概念 来自源码的一张图片,简洁又FengSao +------------+ | BaseServer | +------------+ | v +-----------+ +------------------+ | TCPServer |------->| UnixStreamServer | +-----------+ +------------------+ | v +---

第十七章 Python网络编程

Socket简介 在网络上的两个程序通过一个双向的通信连接实现数据的交换,这个链接的一端称为一个Socket(套接字),用于描述IP地址和端口. 建立网络通信连接至少要一对端口号(Socket),Socket本质是编程接口(API),对TCP/IP的封装,提供了网络通信能力. 每种服务都打开一个Socket,并绑定到端口上,不同的端口对应不同的服务,就像http对应80端口. Socket是面向C/S(客户端/服务器)模型设计,客户端在本地随机申请一个唯一的Socket号,服务器拥有公开的soc