一、socketserver模块介绍

Python提供了两个基本的socket模块。一个是socket,它提供了标准的BSD Socket API; 另一个是socketserver,它提供了服务器中心类,可以简化网络服务器的开发

socketserver

socketserver内部使用IO多路复用以及“多线程”和“多进程”,从而实现并发处理多个客户端请求的socket服务端。 即,每个客服端请求连接到服务器时,socket服务端都会在服务器上创建一个“线程”或“进程”专门负责处理当前客户端的所有请求。

二、socketserver中的ThreadingTCPServer类

ThreadingTCPServer实现的socket服务器内部会为每个client创建一个“线程”,该线程用来和客户端就行交互 ThreadingTCPServer源码内容:

class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass

#可以看到ThreadTCPServer类本身并没有方法,而是继承了(ThreadingMinIn, TCPServer) 这两个类。 而TCPServer则是继承了BaseServer类。

三、ThreadingTCPServer的使用方法

1、创建一个继承socketserver.BaseRequestHandler的类

2、类中必须重写一个名为handler的方法

3、实例化一个服务器类,传入服务器的地址和请求处理程序类

4、调用serve_forever()事件循环监听

#!/usr/bin/env python3
import socketserver class Handler(socketserver.BaseRequestHandler): # 必须继承BaseRequestHandler
def handle(self): # 必须有handle方法
print('New connection:',self.client_address)
while True:
data = self.request.recv(1024)
if not data:break
print('Client data:',data.decode())
self.request.send(data) if __name__ == '__main__':
server = socketserver.ThreadingTCPServer(('127.0.0.1',8009),Handler) # 实例化对象,实现多线程的socket
server.serve_forever() # 事件监听,并调用handler方法

四、ThreadingTCPServer执行过程

1、启动服务端程序

2、执行TCPServer.__init__方法,创建服务端socket对象并绑定IP和端口(根据类的继承关系,即查找顺序找到TCPServer.__init__())

3、执行BaseServer.__init__方法,将自定义的继承自socketserver.BaseRequestHandler的类MyRequestHandler赋值给self.RequestHandlerClass class TCPServer(BaseServer): #(继承了BaseServeer类)

class TCPServer(BaseServer): #(继承了BaseServeer类)
def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True):
"""Constructor. May be extended, do not override."""
BaseServer.__init__(self, server_address, RequestHandlerClass) #(重写了BaseServer的__init__方法)
self.socket = socket.socket(self.address_family,
self.socket_type)
if bind_and_activate:
try:
self.server_bind()
self.server_activate()
except:
self.server_close()
raise class BaseServer:
def __init__(self, server_address, RequestHandlerClass): #(接收了两个传进来的参数)
"""Constructor. May be extended, do not override."""
self.server_address = server_address
self.RequestHandlerClass = RequestHandlerClass #(赋值给了self.RequestHandlerClass)
self.__is_shut_down = threading.Event()
self.__shutdown_request = False

4、通过实例化的对象,执行serve_forever方法,该方法首先查找到BaseServer下的方法,通过调用selector模块,注册事件监听对象,并执行_handle_request_noblock方法 找到此方法,并调用该方法下的process_request方法,在此调用到finish_request方法,通过finish_request方法,执行了RequestHandlerClass方法,执行此方法就相当于调用 了我们重写的Handler类。

class BaseServer:
def serve_forever(self, poll_interval=0.5):
try:
with _ServerSelector() as selector:
selector.register(self, selectors.EVENT_READ) while not self.__shutdown_request:
ready = selector.select(poll_interval)
if ready:
self._handle_request_noblock() self.service_actions()
def _handle_request_noblock(self):
try:
request, client_address = self.get_request()
except OSError:
return
if self.verify_request(request, client_address):
try:
self.process_request(request, client_address)
except Exception:
self.handle_error(request, client_address)
self.shutdown_request(request)
except:
self.shutdown_request(request)
raise
else:
self.shutdown_request(request)
def process_request(self, request, client_address):
self.finish_request(request, client_address)
self.shutdown_request(request)
def finish_request(self, request, client_address):
self.RequestHandlerClass(request, client_address, self)

5、通过Handler类实例化对象,调用继承的BaseRequestHandler类中的__init__方法,并执行了handler方法。 从而运行了我们重写Handler类中的handler方法。

class BaseRequestHandler:
def __init__(self, request, client_address, server):
self.request = request
self.client_address = client_address
self.server = server
self.setup()
try:
self.handle() #调用handler()
finally:
self.finish()

五、调用流程图

socketserver模块使用方法的更多相关文章

  1. python全栈开发day29-网络编程之socket常见方法,socketserver模块,ftp作业

    一.昨日内容回顾 1.arp协议含义 2.子网,子网掩码 3.两台电脑在网络中怎么通信的? 4.tcp和udp socket编码 5.tcp和udp协议的区别 6.tcp三次握手和四次挥手,syn洪攻 ...

  2. socket 和 SocketServer 模块

    一 .Socket 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket socket(TCP,IP)通常也称作"套接字",用于描述IP地址和端 ...

  3. SocketServer模块

    在利用select实现伪并发的socket博文中我们说了: 如果要实现一个server端可以和多个客户端进行通信可以使用 1.多线程 2.多进程 3.select I/O多路复用 在那篇博文中我们介绍 ...

  4. 浅析python中socketserver模块使用

    虽然说用python编写简单的网络程序狠方便,但是复杂一点的网络程序还是用现成的框架比较好,这样就可以专心事物逻辑,而不是套接字的各种细节.Socketserver模块简化了编写网络服务程序,同时so ...

  5. Python网络编程(2)-粘包现象及socketserver模块实现TCP并发

    1. 基于Tcp的远程调用命令实现 很多人应该都使用过Xshell工具,这是一个远程连接工具,通过上面的知识,就可以模拟出Xshell远程连接服务器并调用命令的功能. Tcp服务端代码如下: impo ...

  6. python 内置标准库socketserver模块的思考

    socketserver模块简化了编写网络服务器的任务, 在很大程度上封装了一些操作, 你可以看成是事件驱动型的设计, 这很不错.它定义了两个最基本的类--服务器类 BaseServer, 请求处理类 ...

  7. socketserver模块TCP和UDP协议形式

    # >>>>>>>>>>>>>>>>>>>>服务端socketserver模块通 ...

  8. Python网络编程(3)——SocketServer模块与简单并发服务器

    主要类型 该模块有四个比较主要的类,其中常用的是 TCPServer 和 UDPServer. 1. TCPServer 2. UDPServer 3. UnixStreamServer,类似于TCP ...

  9. python-基于UDP通信的套接字,socketserver模块的使用

    一.基于UDP协议通信的套接字 udp是没有链接的,所以先启动哪一端都不会报错 import socket server=socket.socket(socket.AF_INET,socket.SOC ...

随机推荐

  1. 【正睿多校联盟Day4 T4 简单的数论题】

    题目名有毒 由于并没有系统地开始学习数论,所以数论题基本靠暴力. 然鹅本题的题解相当简单: emmm....我当你没说 一个简单易懂的方法是这样的: 1. 欧拉定理的推论 若正整数a,n互质,则对于任 ...

  2. CentOS 6.2 X64上64位Oracle11gR2 静默安装,静默设置监听,静默建库经验

    1 安装前环境:  操作系统:CetnOS6.2x64 最小化安装,已配置好网络IP:172.16.2.182,物理内存8GB,硬盘100GB.  已下载: Linux.x64_11gR2_datab ...

  3. Hdu 4465 Candy (快速排列组合+概率)

    题目链接: Hdu 4465 Candy 题目描述: 有两个箱子,每个箱子有n颗糖果,抽中第一个箱子的概率为p,抽中另一个箱子的概率为1-p.每次选择一个箱子,有糖果就拿走一颗,没有就换另外一个箱子. ...

  4. bzoj2581 [USACO 2012 Jan Gold] Cow Run【And-Or Tree】

    传送门1:http://www.usaco.org/index.php?page=viewproblem2&cpid=110 传送门2:http://www.lydsy.com/JudgeOn ...

  5. 洛谷 P2062 分队问题

    这题太毒了....一开始就是死活想不到,结果看了很多遍题解,重新做的时候还是做不出来.. 好像有一点被错误的题解误导了? #include<cstdio> #include<algo ...

  6. DP(递归打印路径) UVA 662 Fast Food

    题目传送门 题意:n个饭店在一条直线上,给了它们的坐标,现在要建造m个停车场,饭店没有停车场的要到最近的停车场,问所有饭店到停车场的最短距离 分析:易得区间(i, j)的最短距离和一定是建在(i + ...

  7. Tarjan UVALive 6511 Term Project

    题目传送门 /* 题意:第i个人选择第a[i]个人,问组成强联通分量(自己连自己也算)外还有多少零散的人 有向图强联通分量-Tarjan算法:在模板上加一个num数组,记录每个连通分量的点数,若超过1 ...

  8. 题解报告:NYOJ #311完全背包(恰好装满)

    描述: 直接说题意,完全背包定义有N种物品和一个容量为V的背包,每种物品都有无限件可用.第i种物品的体积是c,价值是w.求解将哪些物品装入背包可使这些物品的体积总和不超过背包容量,且价值总和最大.本题 ...

  9. Java多线程学习---------超详细总结(java 多线程 同步 数据传递 )

    目录(?)[-] 一扩展javalangThread类 二实现javalangRunnable接口 三Thread和Runnable的区别 四线程状态转换 五线程调度 六常用函数说明 使用方式 为什么 ...

  10. 持有对方的引用&&内部类

    现在来做个很简单的东西,就是做一个做加法的图形界面 然后现在先是一个不用持有对方引用的写法: import java.awt.*; import java.awt.event.*; public cl ...