socketserver模块解析

  • socketserver模块是基于socket而来的模块,它是在socket的基础上进行了一层封装,而且实现并发等功能。html

  •  

    • 看看具体用法:node

       
       
       
      x
       
       
       
       
      import socketserver                              #一、引入模块
      class MyServer(socketserver.BaseRequestHandler): #二、本身写一个类,类名本身随便定义,而后继承socketserver这个模块里面的BaseRequestHandler这个类
          def handle(self):              #三、写一个handle方法,必须叫这个名字,不写运行父类的pass
              #self.request             #六、self.request 至关于一个conn
              self.request.recv(1024)                  #七、收消息
              msg = '亲,学会了吗'
              self.request.send(bytes(msg,encoding='utf-8')) #八、发消息
              self.request.close()                     #九、关闭链接
           # 拿到了咱们对每一个客户端的管道,那么咱们本身在这个方法里面的就写咱们接收消息发送消息的逻辑就能够了
              pass
      if __name__ == '__mian__':
          #thread 线程,如今只须要简单理解线程,别着急,后面很快就会讲到啦,看下面的图
          server = socketserver.ThreadingTCPServer(('127.0.0.1',8090),MyServer)#四、使用socketserver的ThreadingTCPServer这个类,将IP和端口的元祖传进去,还须要将上面我们本身定义的类传进去,获得一个对象,至关于咱们经过它进行了bind、listen
          server.serve_forever()                       #五、使用咱们上面这个类的对象来执行serve_forever()方法,他的做用就是说,个人服务一直开启着,就像京东同样,不能关闭网站,对吧,而且serve_forever()帮咱们进行了accept
      #注意:
      #有socketserver 那么有socketclient的吗?
      #固然不会有,我要做为客户去访问京东的时候,京东帮我也客户端了吗,客户端是否是在咱们本身的电脑啊,而且socketserver对客户端没有过高的要求,只须要本身写一些socket就好了
       
    • 简单的应用python

       
       
       
      xxxxxxxxxx
       
       
       
       
      #服务端
      import socketserver
      class Myserver(socketserver.BaseRequestHandler):
          def handle(self):
              self.data = self.request.recv(1024).strip()
              print("{} wrote:".format(self.client_address[0]))
              print(self.data)
              self.request.sendall(self.data.upper())
      if __name__ == "__main__":
          HOST, PORT = "127.0.0.1", 9999
          # 设置allow_reuse_address容许服务器重用地址
          socketserver.TCPServer.allow_reuse_address = True
          # 建立一个server, 将服务地址绑定到127.0.0.1:9999
          #server = socketserver.TCPServer((HOST, PORT),Myserver)
          server = socketserver.ThreadingTCPServer((HOST, PORT),Myserver)
          # 让server永远运行下去,除非强制中止程序
          server.serve_forever()
          
      #客服端
      import socket
      HOST, PORT = "127.0.0.1", 9999
      data = "hello"
      # 建立一个socket连接,SOCK_STREAM表明使用TCP协议
      with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
          sock.connect((HOST, PORT))          # 连接到客户端
          sock.sendall(bytes(data + "\n", "utf-8")) # 向服务端发送数据
          received = str(sock.recv(1024), "utf-8")# 从服务端接收数据
      print("Sent:     {}".format(data))
      print("Received: {}".format(received))
       

       

  • socketserver模块源码解读

    img

    • 从上图咱们能够看出SocketServer主要被抽象为两个主要的类: BaseServer类,用于处理链接相关的网络操做 BaseRequestHandler类,用于实际处理数据相关的操做,SocketServer还提供了两个MixIn类:ThreadingMinxIn和ForkingMixinl 用于扩展server,实现多进程和多线程。web

       
       
       
      xxxxxxxxxx
       
       
       
       
      #如下从这几个主要的类开始作总体分析
      #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对象,并初始化serve地址和处理请求的类: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函数,建立server对象以后咱们会使用server对象开启无限循环,接受一个参数poll_interval,用于表示select轮询的时间,而后进入一个死循环,用select方法进行网络IO的监听,这里经过调用selector.register(self, selectors.EVENT_READ)进行了注册,当ready有返回是,表示有IO链接或者数据,这个时候会调用_handle_request_noblock
      def serve_forever(self, poll_interval=0.5): 
          self.__is_shut_down.clear()
          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()
          finally:
              self.__shutdown_request = False
              self.__is_shut_down.set()
              
      #handlerequest_noblock函数,即开始处理一个请求,而且是非阻塞。该方法经过get_request方法获取链接,具体的实如今其子类。一旦获得了链接,调用verify_request方法验证请求。验证经过,即调用process_request处理请求。若是中途出现错误,则调用handle_error处理错误,以及shutdown_request结束链接,而verify_request中默认直接返回True,因此当验证经过后讲调用process_request
      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:
                  self.handle_error(request, client_address)
                  self.shutdown_request(request)
          else:
              self.shutdown_request(request)
        # process_request函数, process_request方法是mixin的入口,MixIn子类经过重写该方法,进行多线程或多进程的配置 。调用finish_request完成请求的处理,同时调用shutdown_request结束请求.
      def process_request(self, request, client_address):
          self.finish_request(request, client_address)
          self.shutdown_request(request)
          
       #finish_request函数,关于请求的部分到这里就已经处理完毕,接下来是要对数据的处理,finish_request方法将会处理完毕请求.
      #BaseRequestHandler类,用于实际处理数据相关的操做.
      #初始化函数,该类会处理每个请求。初始化对象的时候,设置请求request对象。而后调用setup方法,子类会重写该方法,用于处理socket链接。接下来的将是handler和finish方法。全部对请求的处理,均可以重写handler方法。
      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()
相关文章
相关标签/搜索