一、socketserver流程简介

        +------------+
| BaseServer |
+------------+
|
v
+-----------+ +------------------+
| TCPServer |------->| UnixStreamServer |
+-----------+ +------------------+
|
v
+-----------+ +--------------------+
| UDPServer |------->| UnixDatagramServer |
+-----------+ +--------------------+
# 继承关系如下

class TCPServer(BaseServer):
class UDPServer(TCPServer):
class UnixStreamServer(TCPServer):
address_family = socket.AF_UNIX class UnixDatagramServer(UDPServer):
address_family = socket.AF_UNIX

先来看一下并发聊天的简单例子:

#################### server.py 端
# author:wanstack import socketserver class MyServer(socketserver.BaseRequestHandler): def handle(self):
print ("服务端启动...")
while True:
# conn = sk.accept() 获取到客户端的socket对象
conn = self.request
print (self.client_address)
while True:
client_data=conn.recv(1024)
print (str(client_data,"utf8"))
print ("waiting...")
conn.sendall(client_data)
conn.close() if __name__ == '__main__':
server = socketserver.ThreadingTCPServer(('127.0.0.1',8091),MyServer)
server.serve_forever() ############# client 端
# author:wanstack import socket ip_port = ('127.0.0.1',8091)
sk = socket.socket()
sk.connect(ip_port)
print ("客户端启动:")
while True:
inp = input('>>>')
sk.sendall(bytes(inp,"utf8"))
if inp == 'exit':
break
server_response=sk.recv(1024)
print (str(server_response,"utf8"))
sk.close()

根据上面的例子,我们可以依次看一下socketserver的执行流程,为什么是handle方法来处理咱们的流程。

1、程序先执行

server = socketserver.ThreadingTCPServer(('127.0.0.1',8091),MyServer)

这里看起来像是对一个socketserver 模块下的 ThreadingTCPServer 类进行实例化的过程。接收2个参数第一个参数是一个元组('127.0.0.1',8091)

,第二个参数是我们自定义的类名MyServer

class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass

程序调转到这里,继承(ThreadingMixIn, TCPServer) 2个父类,这个 ThreadingTCPServer 类啥都没干。去父类中找构造函数,先去ThreadingMixIn类中找,如果找不到去TCPServer的类找构造函数。ThreadingMixIn类中没有构造函数,所以构造方法在TCPServer中。

class TCPServer(BaseServer):

    """Base class for various socket-based server classes.

    Defaults to synchronous IP stream (i.e., TCP).

    Methods for the caller:

    - __init__(server_address, RequestHandlerClass, bind_and_activate=True)
- serve_forever(poll_interval=0.5)
- shutdown()
- handle_request() # if you don't use serve_forever()
- fileno() -> int # for selector Methods that may be overridden: - server_bind()
- server_activate()
- get_request() -> request, client_address
- handle_timeout()
- verify_request(request, client_address)
- process_request(request, client_address)
- shutdown_request(request)
- close_request(request)
- handle_error() Methods for derived classes: - finish_request(request, client_address) Class variables that may be overridden by derived classes or
instances: - timeout
- address_family
- socket_type
- request_queue_size (only for stream sockets)
- allow_reuse_address Instance variables: - server_address
- RequestHandlerClass
- socket """ address_family = socket.AF_INET socket_type = socket.SOCK_STREAM request_queue_size = 5 allow_reuse_address = False def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True):
"""Constructor. May be extended, do not override."""
# 这里是执行的BaseServer的构造方法,只是执行了一些赋值操作
BaseServer.__init__(self, server_address, RequestHandlerClass)
# 创建socket的对象,是基于IPV4和TCP协议的
self.socket = socket.socket(self.address_family,
self.socket_type)
if bind_and_activate:
try:
# 下面的bind()方法,bind我们传入的ip和port
self.server_bind()
# 这里是listen(),默认为5个
self.server_activate()
except:
self.server_close()
raise def server_bind(self):
"""Called by constructor to bind the socket. May be overridden. """
if self.allow_reuse_address:
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.socket.bind(self.server_address)
self.server_address = self.socket.getsockname() def server_activate(self):
"""Called by constructor to activate the server. May be overridden. """
self.socket.listen(self.request_queue_size) def server_close(self):
"""Called to clean-up the server. May be overridden. """
self.socket.close()

程序到这里我们就执行完了构造方法。下面开始执行

server.serve_forever()

请务必记住这里的server是  socketserver.ThreadingTCPServer(('127.0.0.1',8091),MyServer) 实例化的对象。

根据查询流程

ThreadingTCPServer ---> ThreadingMixIn ---> TCPServer ---> BaseServer 最终在BaseServer类中找到了

socketserver源码简介的更多相关文章

  1. Python之socketserver源码分析

    一.socketserver简介 socketserver是一个创建服务器的框架,封装了许多功能用来处理来自客户端的请求,简化了自己写服务端代码.比如说对于基本的套接字服务器(socket-based ...

  2. 自己实现多线程的socket,socketserver源码剖析

    1,IO多路复用 三种多路复用的机制:select.poll.epoll 用的多的两个:select和epoll 简单的说就是:1,select和poll所有平台都支持,epoll只有linux支持2 ...

  3. (原创)通用查询实现方案(可用于DDD)[附源码] -- 简介

    [声明] 写作不易,转载请注明出处(http://www.cnblogs.com/wiseant/p/3985353.html).   [系列文章] 通用查询实现方案(可用于DDD)[附源码] -- ...

  4. python_way day10 python和其他语言的作用域 、 python2.7多继承和3.5多继承的区别 、 socket 和 socketserver源码(支持并发处理socket,多进程,多线程)

    python_way day10 1.python的作用域和其他语言的作用域 2.python2.7多继承和3.5多继承的区别 3.socket和socketserver源码(并发处理socket) ...

  5. Linux内核分析(一)---linux体系简介|内核源码简介|内核配置编译安装

    原文:Linux内核分析(一)---linux体系简介|内核源码简介|内核配置编译安装 Linux内核分析(一) 从本篇博文开始我将对linux内核进行学习和分析,整个过程必将十分艰辛,但我会坚持到底 ...

  6. 解读python中SocketServer源码

    在看SocketServer源码之前,先看一个例子: class Base(object): def __init__(self, name): self.name = name self.Testf ...

  7. dJango前言之 socketserver源码

    socketserver源码分析: ftpserver=socketserver.ThreadingTCPServer(('127.0.0.1',8080),FtpServer) ftpserver. ...

  8. 解读socketserver源码

    解读python中SocketServer源码 再看继承 真正的大餐来之前,还是来点儿开胃菜!回顾一下关于类的继承的知识:    我们先看上面的代码,这是一个简单的类继承,我们可以看到父类Base和子 ...

  9. 文件上传下载、socketserver(并发)、解读socketserver源码

    1.文件上传/下载 学习了socket套接字,我们现在可以写一个文件上传/下载的程序,如下示例: 分析上边代码,我们发现,client发送上传文件相关信息的字典序列化之后,server又给client ...

随机推荐

  1. C# 各种导入 Excel 文件的数据的方法总结

    在导入之前都需要将上传的文件保存到服务器,所以避免重复的写这些代码,先贴出上传文件并保存到服务器指定路径的代码. protected void btnImport_Click(object sende ...

  2. [笔记] Ubuntu 18.04安装cuda 10及cudnn 7流程

    安装环境 OS:Ubuntu 18.04 64 bit 显卡:NVidia GTX 1080 任务:安装 CUDA 10及cuDNN 7 工具下载 NVidia官网下载下列文件: CUDA 10:cu ...

  3. PL/SQL编程-块编程

    (1). 简单分类                           |————过程(存储过程)                           |                        ...

  4. web前端基础——初识JavaScript

    1 JavaScript概述 JavaScript是一种属于网络的脚本语言,已经被广泛用于Web应用开发,常用来为网页添加各式各样的动态功能,为用户提供更流畅美观的浏览效果.通常JavaScript脚 ...

  5. 关于Android RenderScript 的详细说明和一些实用文档

    http://www.cnblogs.com/TerryBlog/archive/2012/03/02/2377251.html RenderScript 是一种低级的高性能编程语言,用于3D渲染和处 ...

  6. 软件测试技术作业3---PrintPrimes()

    一.代码部分: private static void printPrimes (int n) { int curPrime; // Value currently considered for pr ...

  7. 20145211《网络渗透》MS12-004漏洞渗透

    20145211<网络渗透>MS12-004漏洞渗透 一 实验原理 初步掌握平台matesploit的使用 有了初步完成渗透操作的思路 在这里我选择对的不是老师推荐的MS11_050,而是 ...

  8. Jquery10 高级事件

    学习要点: 1.模拟操作 2.命名空间 3.事件委托 4.on.off 和 one jQuery 不但封装了大量常用的事件处理,还提供了不少高级事件方便开发者使用.比如模拟用户触发事件.事件委托事件. ...

  9. Ubuntu16.04多个版本GCC编译器的安装和切换【转】

    本文转载自:https://www.cnblogs.com/uestc-mm/p/7511063.html 这几天在配置交叉编译ARM开发板的linux内核的过程中碰到了很多问题,其中包括了GCC版本 ...

  10. Maven 修改默认JDK版本

    方式1.修改maven全局jdk 修改 安装目录\maven2\conf\settings.xml <profiles> <profile> <id>jdk-1.6 ...