socketserver源码简介
一、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源码简介的更多相关文章
- Python之socketserver源码分析
一.socketserver简介 socketserver是一个创建服务器的框架,封装了许多功能用来处理来自客户端的请求,简化了自己写服务端代码.比如说对于基本的套接字服务器(socket-based ...
- 自己实现多线程的socket,socketserver源码剖析
1,IO多路复用 三种多路复用的机制:select.poll.epoll 用的多的两个:select和epoll 简单的说就是:1,select和poll所有平台都支持,epoll只有linux支持2 ...
- (原创)通用查询实现方案(可用于DDD)[附源码] -- 简介
[声明] 写作不易,转载请注明出处(http://www.cnblogs.com/wiseant/p/3985353.html). [系列文章] 通用查询实现方案(可用于DDD)[附源码] -- ...
- 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) ...
- Linux内核分析(一)---linux体系简介|内核源码简介|内核配置编译安装
原文:Linux内核分析(一)---linux体系简介|内核源码简介|内核配置编译安装 Linux内核分析(一) 从本篇博文开始我将对linux内核进行学习和分析,整个过程必将十分艰辛,但我会坚持到底 ...
- 解读python中SocketServer源码
在看SocketServer源码之前,先看一个例子: class Base(object): def __init__(self, name): self.name = name self.Testf ...
- dJango前言之 socketserver源码
socketserver源码分析: ftpserver=socketserver.ThreadingTCPServer(('127.0.0.1',8080),FtpServer) ftpserver. ...
- 解读socketserver源码
解读python中SocketServer源码 再看继承 真正的大餐来之前,还是来点儿开胃菜!回顾一下关于类的继承的知识: 我们先看上面的代码,这是一个简单的类继承,我们可以看到父类Base和子 ...
- 文件上传下载、socketserver(并发)、解读socketserver源码
1.文件上传/下载 学习了socket套接字,我们现在可以写一个文件上传/下载的程序,如下示例: 分析上边代码,我们发现,client发送上传文件相关信息的字典序列化之后,server又给client ...
随机推荐
- Linux系统——最小化安装
一.虚拟机进行Linux minimal 安装 网络连接:选择“自定义”——>VMnet8(NAT模式) #PC与NAT网络的虚拟机在不同网段,此时虚拟网卡作为网关建立通信 NAT模式可直接上I ...
- javascript 类型 内存 对象
var box =0 function test() { alert(box) //全局 }
- dev-server.js详解
转载自:https://www.cnblogs.com/ye-hcj/p/7091706.html dev-server.js详解 require('./check-versions')() var ...
- 127. Word Ladder(单词变换 广度优先)
Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest t ...
- Unity状态机的实现,以《塔防》为例
什么是有限状态机? 通俗点讲,有限状态机是:将对象的状态(攻击.闲置.晕眩)的实现代码,提取出来,封装成状态.由状态机负责在各个状态之间调度. 对象持有状态管理类(状态机)的引用,与具体的状态解耦. ...
- ElasticSearch(三) ElasticSearch中文分词插件IK的安装
正因为Elasticsearch 内置的分词器对中文不友好,会把中文分成单个字来进行全文检索,所以我们需要借助中文分词插件来解决这个问题. 一.安装maven管理工具 Elasticsearch 要使 ...
- RabbitMQ 高级指南
1 RabbitMQ 简介 1.1 介绍 RabbitMQ 是一个由 erlang 开发的基于 AMQP(Advanced Message Queue)协议的开源实现.用于在分布式系统中存储转发消息, ...
- Hive创建一个简单的UDF
创建一个类 package com.dufeng.hive; import org.apache.commons.lang.StringUtils; import org.apache.hadoop. ...
- [BZOJ3669]魔法森林
Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N,边标号为1..M.初始时小E同学在号节 ...
- LeetCode——minimum-path-sum
Question Given a m x n grid filled with non-negative numbers, find a path from top left to bottom ri ...