码迷,mamicode.com
首页 > 其他好文 > 详细

socketserver模块使用方法

时间:2018-08-19 21:49:37      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:cti   bind   self   usr   多个   over   多路复用   处理程序   main   

一、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方法
View Code

四、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
View Code

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)
View Code

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()
View Code

五、调用流程图

技术分享图片

socketserver模块使用方法

标签:cti   bind   self   usr   多个   over   多路复用   处理程序   main   

原文地址:https://www.cnblogs.com/jeavy/p/9502555.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!