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类中找到了
时间: 2024-08-01 18:33:45

socketserver源码简介的相关文章

socketserver 源码剖析:

socketserver 源码剖析[有图有真相]: (一).Socketserver 内部流程调用图:        详解: 1.self.RequestHandlerClass() = MyClass() 转换为 执行这个方法 class MyClass(socketserer.BaseRquestHandler). 2. myclass 没有构造方法 __init__( ),从socketserer.BaseRquestHandler 父类 开始找,有构造函数 __init__( ),并且执

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

原文:Linux内核分析(一)---linux体系简介|内核源码简介|内核配置编译安装 Linux内核分析(一) 从本篇博文开始我将对linux内核进行学习和分析,整个过程必将十分艰辛,但我会坚持到底,同时在博文中如果那些地方有问题还请各位大神为我讲解. 今天我们会分析到以下内容: 1.      Linux体系结构简介 2.      Linux内核源码简介 3.      Linux内核配置.编译.安装 l  Linux体系结构简介 1.       Linux体系结构(linux系统构成)

QtCreator源码分析(一)——QtCreator源码简介

QtCreator源码分析(一)--QtCreator源码简介 一.QtCreator简介 QtCreator是设计精巧的插件式系统,QtCreator的核心是一个插件管理器,其所有功能都是使用插件完成.在启动时,QtCreator会首先加载一个名为coreplugin的插件,coreplugin插件提供了Qt Creator最基本的功能和扩展点,其余的插件都是直接或间接依赖于coreplugin插件提供的机制,一步步扩充QtCreator的功能,最终将其变成一个功能完整的IDE.针对QtCre

自动化运维Python系列之IO多路复用、SocketServer源码分析

IO多路复用 IO多路复用是指:通过一种机制,可以监视多个描述符,一旦某个系统描述符就绪(一般是读就绪或者写就绪)能够通知程序进行相应的读写操作 实例化例子就是在SocketServer模块中,客户端和服务端建立好连接,此时服务端通过监听conn这条链路,一旦客户端发送了数据,conn链路状态就发生变化,服务端就知道有数据要接收... Linux系统中同时存在select.pull.epoll三种IO多路复用机制 windows中只有select机制 1)select select本质上是通过设

socketserver源码解析和协程版socketserver

来,贴上一段代码让你仰慕一下欧socketserver的魅力,看欧怎么完美实现多并发的魅力 client import socket ip_port = ('127.0.0.1',8009) sk = socket.socket() sk.connect(ip_port) sk.settimeout(5) while True: data = sk.recv(1024) print('receive:',data.decode()) inp = input('please input:') sk

socketserver源码剖析

这里选择的是python2.7(python3和2.7的源码基本类似) #!/usr/bin/env python # -*- coding:utf-8 -*- import SocketServer class MyServer(SocketServer.BaseRequestHandler): def handle(self): conn = self.request conn.sendall(bytes("欢迎致电老男孩", encoding="utf-8")

由socketserver源码引出的类的继承关系

当我们拿到一份python源代码,我们要怎么去看呢? 下面我们以socketserver为例,看下面的一段代码: 1 #!/usr/bin/env python 2 # -*- coding: UTF-8 -*- 3 # Author: ZCX 4 5 import socketserver #导入socketserver模块 6 7 8 class MyServer(socketserver.BaseRequestHandler): #定义一个类 9 def handle(self): #定义

SocketServer源码学习(一)

SocketServer其实是对socket更高级的封装正如官网上说的:The socketserver module simplifies the task of writing network servers. 我们可以先打开以下SocketServer的源码,看一下源码中整体的框架 从上图我们可以看出SocketServer主要被抽象为两个主要的类:BaseServer类,用于处理连接相关的网络操作BaseRequestHandler类,用于实际处理数据相关的操作 SocketServer

linux源码简介

linux用来支持各种体系结构的源代码包含大约4500个C语言程序,存放在270个左右的子目录下,总共大约包含200万行代码,大概占用58MB磁盘空间. http://blog.csdn.net/liaoshengjiong/article/details/3957654 kernel-3.10.0-123.el7.src.rpm 源代码所有在目录:/usr/src/linux (大部分linux发行版本中) ■arch 平台相关代码   ◆i386 IBM的PC体系结构     ◇kernel