一、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. centos6.8安装zabbix

    前后用了两台电脑来实验,前后画风不一样,请忽略 一.安装php环境 移除目前系统安装的 PHP 组件 yum remove php* -y 安装 PHP 的 YUM 源  rpm -Uvh http: ...

  2. phpcms v9模板制作常用代码集合

    phpcms v9模板制作常用代码集合(个人收藏) 1.截取调用标题长度 {str_cut($r[title],36,'')} 2.格式化时间 调用格式化时间 2011-05-06 11:22:33 ...

  3. Divide by Zero 2017 and Codeforces Round #399 (Div. 1 + Div. 2, combined) B. Code For 1

    地址:http://codeforces.com/contest/768/problem/B 题目: B. Code For 1 time limit per test 2 seconds memor ...

  4. 在VS2012中采用C++中调用DLL中的函数(4)

    转自:http://www.cnblogs.com/woshitianma/p/3683495.html 这两天因为需要用到VS2012来生成一个DLL代码,但是之前并没有用过DLL相关的内容,从昨天 ...

  5. Windows Update error 80070003

    上次更新完成一半,这次更新便会出错.办法:删除上次更新残余文件. 删除Windows 用于标识计算机更新的临时文件.需要先停止Windows Update 服务: 在开始菜单的“搜索程序和文件”框输入 ...

  6. Eclipse安装Activiti插件(流程设计器)

    Eclipse安装Activiti插件(流程设计器) 一.安装步骤: 1,打开Eclipse的 Help -> Install New Software,填上插件地址: Name:Activit ...

  7. Visual Studio 2015 初体验

    据微软介绍每次发布的新版本,都承载着为开发者提供最高效的Visual Studio开发体验的使命.Visual Studio 2015亦延续了这一趋势,为开发者带来了进一步的生产力创新,包括调试和诊断 ...

  8. 配置linux使用mail发送邮件到163邮箱

    1.进行配置 yum install -y mailx /etc/mail.rc添加对163的授权: ##########config 163 mail############set from=jso ...

  9. KVM配置及维护

    kvm使用场景 1.公司测试环境/开发环境 测试开发环境可以使用配置低点的物理机就可以 2.公司生产环境 一般小公司没有私有云或容器团队,运维人员可能就1-2个,然后公司也不舍得花钱买商业化的私有云. ...

  10. js 自定义事件观察者模式(发布/订阅)

    /* * 示例: * Event.create("namespace1").listen('click', function(a){ * console.log(a); * }); ...