zoukankan      html  css  js  c++  java
  • 网络编程之socketserver

    网络编程之socketserver
    """
    socketserver.py 中的5个基础类
            +------------+
            | BaseServer |
            +------------+
                  |
                  v
            +-----------+        +------------------+
            | TCPServer |------->| UnixStreamServer |
            +-----------+        +------------------+
                  |
                  v
            +-----------+        +--------------------+
            | UDPServer |------->| UnixDatagramServer |
            +-----------+        +--------------------+
    """
    socketserver简单概括
    __version__ = "0.4"
    import socket
    import selectors
    import os
    import errno
    import sys
    try:
        import threading
    except ImportError:
        import dummy_threading as threading
    from io import BufferedIOBase
    from time import monotonic as time
    
    # __all__属性由列表构成,它规定了模块的所有可见方法,会使属性列表之外的成员全部私有化。
    __all__ = ["BaseServer", "TCPServer", "UDPServer",
               "ThreadingUDPServer", "ThreadingTCPServer",
               "BaseRequestHandler", "StreamRequestHandler",
               "DatagramRequestHandler", "ThreadingMixIn"]
    
    if hasattr(os, "fork"):
        __all__.extend(["ForkingUDPServer","ForkingTCPServer", "ForkingMixIn"])
        
    if hasattr(socket, "AF_UNIX"):  # 如果socket类型是AF_UNIX则将下面的添加到列表中
        __all__.extend(["UnixStreamServer","UnixDatagramServer",
                        "ThreadingUnixStreamServer",
                        "ThreadingUnixDatagramServer"])
        
    if hasattr(selectors, 'PollSelector'):
        _ServerSelector = selectors.PollSelector
    else:
        _ServerSelector = selectors.SelectSelector
    
    class BaseServer:  # 基础服务类
        
    class TCPServer(BaseServer):  # Tcp类
    
    class UDPServer(TCPServer):  # UDP类
        
    if hasattr(os, "fork"):
        class ForkingMixIn:  # 提供多进程功能的类
            
    class ThreadingMixIn:  # 提供多线程功能的类
    
    if hasattr(os, "fork"):
        class ForkingUDPServer(ForkingMixIn, UDPServer):  # UDP多进程类,实际就是继承了ForkingMixIn和UDPServer而已
        class ForkingTCPServer(ForkingMixIn, TCPServer):  # TCP多进程类,实际就是继承了ForkingMixIn和TCPServer而已
            
    class ThreadingUDPServer(ThreadingMixIn, UDPServer):  # UDP多线程类,实际就是继承了ThreadingMixIn和UDPServer而已
    class ThreadingTCPServer(ThreadingMixIn, TCPServer):  # TCP多线程类,实际就是继承了ThreadingMixIn和TCPServer而已
    
    if hasattr(socket, 'AF_UNIX'):  # 如果你的socket是AF_UNIX族,则定义下面4个类
        class UnixStreamServer(TCPServer):
        class UnixDatagramServer(UDPServer):
        class ThreadingUnixStreamServer(ThreadingMixIn, UnixStreamServer):
        class ThreadingUnixDatagramServer(ThreadingMixIn, UnixDatagramServer):
    
    class BaseRequestHandler:  # 业务逻辑类
        
    class StreamRequestHandler(BaseRequestHandler):  # TCP相关的业务逻辑
    class _SocketWriter(BufferedIOBase):
    class DatagramRequestHandler(BaseRequestHandler):  # UDP相关业务逻辑
    
    """
    总结:
    socketserver.py 实际上就是封装了TCP服务UDP服务,多线程TCP服务,多线程UDP服务,多进程TCP服务,多进程UDP服务的类
    
    TCPServer(BaseServer)  # TCP类
    UDPServer(TCPServer)   # UDP类
    ForkingTCPServer(ForkingMixIn, TCPServer)  # 多进程TCP类
    ForkingUDPServer(ForkingMixIn, UDPServer)  # 多进程UDP类
    ThreadingTCPServer(ThreadingMixIn, TCPServer)  # 多线程TCP类
    ThreadingUDPServer(ThreadingMixIn, UDPServer)  # 多线程UDP类
    StreamRequestHandler(BaseRequestHandler):  # TCP相关的业务逻辑
    DatagramRequestHandler(BaseRequestHandler):  # UDP相关业务逻辑
    """
    View Code
    socketserver各个类之间的关系
    #!/usr/bin/env python
    # @Author   : "Wjl"
    # @Date     : 2017/12/22
    # @Time     : 15:12
    # @SoftWare : PyCharm
    # @File     : Test_Server.py
    
    """
    通过下面的类创建基础服务:
     如果是AF_INET                                                                           
     +-----------+        +------------------+        +--------------------+           
     | TCPServer |------->| ForkingTCPServer |   or   | ThreadingTCPServer |           
     +-----------+        +------------------+        +--------------------+           
     
     +-----------+        +------------------+        +--------------------+           
     | UDPServer |------->| ForkingUDPServer |   or   | ThreadingUDPServer |           
     +-----------+        +------------------+        +--------------------+
    
     如果是AF_UNIX
     +----------------+        +-------------------------+
     |UnixStreamServer|------->|ThreadingUnixStreamServer|
     +----------------+        +-------------------------+ 
      
     +------------------+        +---------------------------+ 
     |UnixDatagramServer|------->|ThreadingUnixDatagramServer|
     +------------------+        +---------------------------+
    
    再将你的逻辑写在如下类中的handle方法中(),传递给上面的类,来调用
     +--------------------+        +----------------------+        +------------------------+    
     | BaseRequestHandler |------->| StreamRequestHandler |   or   | DatagramRequestHandler |   
     +--------------------+        +----------------------+        +------------------------+ 
    
    """
    import socketserver
    
    class MyServer(socketserver.StreamRequestHandler):  # 继承业务逻辑类
        def handle(self):  # 将你的业务逻辑写在handle方法中
            print("服务端启动...")
            while True:
                conn = self.request  # self.request就是客户端的socket对象
                print(self.client_address)  # 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.TCPServer(('127.0.0.1', 8888), MyServer)  # 创建TCP服务,将业务逻辑传递给它,好让服务和业务逻辑关联起来
        server.serve_forever()  # 通过forever()方法来接收请求,其实就是调用了socket.accept方法
        # server.handle_request()  # 还可以调用handle_request()来处理请求

    总结:

    想要玩转socketserver

    1.首先需要明确使用什么地址簇, 是 AF_INET还是UX_INET

    2.明确是使用TCP还是UDP,以此来确定是使用哪个类

    3.明确有没有用到多线程或多进程

    4.根据2来选择对应的业务逻辑类来处理

  • 相关阅读:
    ES6中的新特性
    怎样优化CPU
    es6 一些小知识
    ECMAScript有6种继承方式(实现继承)
    angula的factory service provider
    angular的继承作用域通信
    MVP和MVC的区别
    判断浏览器版本语句大全
    IScroll5+在ios、android点击(click)事件不兼容解决方法
    css中单位px和em,rem的区别
  • 原文地址:https://www.cnblogs.com/xiaofengchu/p/8461199.html
Copyright © 2011-2022 走看看