旁边东华帝君早将手按在剑柄上,勾陈上帝叹道:“不想我与观音菩萨也有交手这一日。”

李庆安淡淡一笑,这少年好大的口气,他瞥了一眼独孤明月,见她两颊笑涡霞光荡漾,刚才的忧伤竟一扫而空,李庆安心中有些醒悟了,原来她是喜欢对面这个少年郎.....

广州日结兼职

将小蜜蜂收回蜂巢,王小民查看了一下那些包装盒,里面的灵药果然都变成了灰渣。
“那其他三家的老太爷,都多大岁数了?”王小民随口问道,其实他问这个也只是无聊而已。

叶扬的眼前则是浮现出了脑域一号的身影,不管怎么说,脑域一号应该属于自己的师父吧。可是她的形象,叶扬嘴角微微抽了抽。

SocketServer源码学习(一)


SocketServer其实是对socket更高级的封装正如官网上说的:
The socketserver module simplifies the task of writing network servers.

我们可以先打开以下SocketServer的源码,看一下源码中整体的框架

从上图我们可以看出SocketServer主要被抽象为两个主要的类:
BaseServer类,用于处理连接相关的网络操作
BaseRequestHandler类,用于实际处理数据相关的操作

SocketServer还提供了两个MixIn类:ThreadingMinxIn和ForkingMixinl
用于扩展server,实现多进程和多线程

下面从会从这几个主要的类开始做一个整体的分析,了解SocketServer的处理流程

 

BaseServer

先列一下这里所包含的方法:
server_activate
serve_forever
shutdown
service_actions
handle_request
handlerequest_noblock
handle_timeout
verify_request
process_request
server_close
finish_request
shutdown_request
close_request
handle_error

先看一下BaseServer的初始化函数,其实并没有过多的参数,主要就是实现了创建server对象,并初始化server地址和处理请求的类:RequestHandlerClass

def __init__(self, server_address, RequestHandlerClass):
    """Constructor.  May be extended, do not override."""
    self.server_address = server_address
    self.RequestHandlerClass = RequestHandlerClass
    self.__is_shut_down = threading.Event()
    self.__shutdown_request = False

serve_forever

先看一下源码内容如下:

def serve_forever(self, poll_interval=0.5):
    """Handle one request at a time until shutdown.

    Polls for shutdown every poll_interval seconds. Ignores
    self.timeout. If you need to do periodic tasks, do them in
    another thread.
    """
    self.__is_shut_down.clear()
    try:
        # XXX: Consider using another file descriptor or connecting to the
        # socket to wake this up instead of polling. Polling reduces our
        # responsiveness to a shutdown request and wastes cpu at all other
        # times.
        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()
    finally:
        self.__shutdown_request = False
        self.__is_shut_down.set()

当创建server对象之后,我们会使用server对象开启一个无限循环,即调用serve_forever,
下面是它的源码,接受一个参数poll_interval,用于表示select轮询的时间,然后进入一个死循环,用select方法进行网络IO的监听,这里通过调用selector.register(self, selectors.EVENT_READ)进行了注册,当ready有返回是,表示有IO连接或者数据,这个时候会调用_handle_request_noblock
接着看一下_handle_request_noblock源码

handlerequest_noblock

源码内容如下:

def _handle_request_noblock(self):
    """Handle one request, without blocking.

    I assume that selector.select() has returned that the socket is
    readable before this function was called, so there should be no risk of
    blocking in get_request().
    """
    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:
            self.handle_error(request, client_address)
            self.shutdown_request(request)
    else:
        self.shutdown_request(request)

handlerequest_noblock方法即开始处理一个请求,并且是非阻塞。该方法通过get_request方法获取连接,具体的实现在其子类。一旦得到了连接,调用verify_request方法验证请求。验证通过,即调用process_request处理请求。如果中途出现错误,则调用handle_error处理错误,以及shutdown_request结束连接。

而verify_request中默认直接返回True,所以当验证通过后讲调用process_request

process_request

源码内容如下:

def process_request(self, request, client_address):
    """Call finish_request.

    Overridden by ForkingMixIn and ThreadingMixIn.

    """
    self.finish_request(request, client_address)
    self.shutdown_request(request)

就像源码中描述的那样:Overridden by ForkingMixIn and ThreadingMixIn.
process_request方法是mixin的入口,MixIn子类通过重写该方法,进行多线程或多进程的配置。调用finish_request完成请求的处理,同时调用shutdown_request结束请求。继续查看finish_request

finish_request

源码内容如下:

def finish_request(self, request, client_address):
    """Finish one request by instantiating RequestHandlerClass."""
    self.RequestHandlerClass(request, client_address, self)

关于请求的部分到这里就已经处理完毕,接下来是要对数据的处理,finish_request方法将会处理完毕请求。创建requestHandler对象,并通过requestHandler做具体的处理。

BaseRequestHandler

就像我们前面说的:
BaseServer类,用于处理连接相关的网络操作
BaseRequestHandler类,用于实际处理数据相关的操作

还是从初始化函数里看源码:

def __init__(self, request, client_address, server):
    self.request = request
    self.client_address = client_address
    self.server = server
    self.setup()
    try:
        self.handle()
    finally:
        self.finish()

该类会处理每一个请求。初始化对象的时候,设置请求request对象。然后调用setup方法,子类会重写该方法,用于处理socket连接。接下来的将是handler和finish方法。所有对请求的处理,都可以重写handler方法。

SocketServer的一个服务端的简单例子

直接上代码了:

import socketserver


class MyTCPHandler(socketserver.BaseRequestHandler):
    def handle(self):
        while True:
            try:
                self.data = self.request.recv(1024).strip()
                print("{} wrote:".format(self.client_address))
                print(self.data)
                self.request.sendall(self.data.upper())
            except ConnectionResetError as e:
                print(e)
                break

if __name__ == "__main__":
    host,port = "127.0.0.1",9999
    server = socketserver.TCPServer((host,port),MyTCPHandler)
    server.serve_forever()

通过对源码的分析我们已经知道了对数据的处理部分都是在BaseRequestHandler这个类中,而我们的主要处理逻辑也就是在这部分,所以我继承了这个类,重写了handle方法

 

当前文章:http://hnhdqp.com/home/53umeiu7gm.html

发布时间:2018-12-15 00:40:37

正规淘宝刷单兼职qq群 打字员免费入职兼职 肯德基兼职招聘信息 网购刷信誉兼职可靠吗 有没有安全的网上兼职工作? 微信兼职群 学生微信代理兼职 诚聘兼职会计郑州

编辑:丁伯

相关新闻

有钱不一定成功,但在中国可能例外

2018-12-15 00:54:36

塔城娜抛辛传媒广告有限公司

能量源 推开量子保健的大门

2018-12-15 00:36:00

南通嘏捶美术工作室

【观点】电子猫眼进入智能时代

2018-12-15 00:32:57

济宁从贡信用担保有限公司

朱婷进攻不多却合古德蒂心意 两大作用更被看重

2018-12-15 00:39:31

宁德玖装图美容美发化妆学校

热门推荐

  • QS世界大学学科排名发布 清华4个学科居全球前10
  • Excel数据透视表“空白”?教你轻松解决
  • 高校宿舍贴化学元素新春对联 网友:逼死文科生
  • 揭网络抢购软件面纱:体系化运作 研发销售一条龙
  • 津巴布韦外交部和国防军举行吹风会 否认发生政变
  • 《画江山》新资料片即将开启 这些活动让你时来运转
  • 《Dies irae》动画第4话先行图 红蜘蛛大叔重创男主
  • 游戏全屏比窗口更快?显卡驱动这些秘密你知多少
  • 台军再传丑闻:搭军机叫性招待 因付账与店家起争执
  • 他孤身留在云南19年 只为寻找17具遗体
  • 河北新闻网版权所有 本站点信息未经允许不得复制或镜像 法律顾问:手机赚钱app新闻 什么游戏挂机赚钱
  • 网上打码赚钱软件 copyright ? 2000 - 2016
  • 新闻热线:0311-67563366 广告热线:0311-67562966 新闻投诉:0311-67562994
  • 冀ICP备 09047539号-1 | 互联网新闻信息服务许可证编号:1312006002
  • 广播电视节目制作经营许可证(冀)字第101号|信息网络传播视听节目许可证0311618号
  • 日赚兼职 网上兼职挣钱的方法 手机兼职赚钱正规网站 答题赚钱1-6元