zoukankan      html  css  js  c++  java
  • Python_socketserver

    socketserver ----->> 服务器端的开发

    socketserver:   实现服务器端同时处理多个请求

    通过两个主要的类来处理网络请求:

    • 服务类
    • 请求处理类

    一、服务类

    1. 基础同步服务器

    BaseServer

           |    继承

          V

    TCPServer   —继承—>  UnixStreamServer

          |     继承

         V

    UDPServer  —继承—>  UnixDatagramServer

    其中,Baseserver不直接对外服务,而是通过TCPSever/ UDPServer 对外服务

    TCPServer(address,handler) 支持使用IPv4的TCP协议的服务器,address是一个(地址,端口号)元组,handler是BaseRequestHandler或StreamRequestHandler类的子类实例
    UDPServer(address,handler) 支持使用IPv4的UDP协议的服务器,handler是BaseRequestHandler或DataStreamRequestHandler类的子类实例
    UnixStreamServer(address,handler) 使用Unix域套接字实现面向数据流协议的服务器
    UnixDatagramServer(address,handler) 使用Unix域套接字实现数据报协议的服务器

    以上四个服务类的实例都有以下方法和变量(部分)(实际上都来自于父类soketserver.BaseServer):

    BaseServer.socket 用于传入请求的套接字对象
    BaseServer.server_address 监听服务器的(地址,端口号)元组
    BaseServer.RequestHandlerClass                                         传递给服务器构造函数并由用户提供的请求处理程序类
    BaseServer.serve_forever() 处理无限请求,直到一个明确的shutdown()请求
    BaseServer.service_action() 在serve_forever循环中被调用
    BaseServer.shutdown() 停止serve_forever()循环,并等待直到它结束
    BaseServer.server_close() 清理服务器(可能会被覆盖)

    BaseServer.handle_request                                                                                                                           

    处理一个请求,这个函数调用下面的方法依次是:get_request(),verify_request(),和process_request()。如果handle() 处理程序类的用户提供的方法引发异常,handle_error则将调用服务器方法,如果在timeout几秒内没有收到请求,handle_timeout() 将会被调用handle_request()返回。
    BaseServer.fileno() 返回服务器正在监听的套接字的整数文件描述符,这个功能通常被传递给selector,允许在同一个进程中监视多个服务器
    BaseServer.address_family 服务器套接字所属的协议族,例:socket.AF_INET,socket.AF_UNIX

    2.自定义异步服务器

    • ForkingMinIn:(不直接对外服务)为每一个客户端请求派生一个新的进程去专门处理
    • ThreadingMinIn:(不直接对外服务)为每一个客户端请求派生一个新的线程去专门处理

    sockserver 通过继承 ForKingMinIn和ThreadingMinIn预定义了以下几个可并发的服务类:

    • ForKingUDPServer(address,handler): UDP多进程
    • ForkingTCPServer(address,handler):TCP多进程
    • ThreadingUDPServer(address,handler) :UDP多线程
    • ThreadingTCPServer(address,handler):TCP多线程

    二、请求处理类

    通常需要继承BaserequestHandler, 并重写handle() 方法,当一个网络请求被创建时,一个新的实例就会被创建。

    方法如下:

    setup(): 在handle() 被调用前被执行,一般用于一些初始化操作,默认不执行任何操作

    handle(): 当一个请求到来后,用户所要执行的操作,这个方法应被重写,操作self.reequest

    finish(): handle() 之后被调用的函数,用于执行一个清理工作

    三、如何创建一个socketserver

    1. 根据需要选择一个合适和服务类型,如,面向TCP连接的多线程服务器:ForKingTCPServer
    2. 创建一个请求处理的类,并且这个类要继承BaseRequestHanderclass,并且还要重写父类里handle() 方法
    3. 实例化服务器(如:TCPServer),并传递server IP和你上面创建的请求处理类,给这个TCPServer
    4. 调用服务器实例的请求方法:server.handle_requese() # 只处理一个请求,server.serve_forever() # 处理多个请求,永远执行
    5. 关闭连接server_close()

     实例:

    import socketserver
    class myTCPHandler(socketserver.BaseRequestHandler):
        def handle(self):           # 尤其注意  “ handle ” 为固定值
            print("客户端地址:",self.client_address)         # 客户端IP地址 和端口号(字符串)
            while True:
                data = self.request.recv(1024)
                if not data:break
                print("客户端发来消息 :",data.decode('utf8'))
                self.request.send(data)
    
    if __name__ =='__main__':
    
        HOST,PORT = "localhost" , 9999
    
        serve = socketserver.ThreadingTCPServer((HOST,PORT),myTCPHandler)
        serve.serve_forever()    # server 一直运行
    异步_ 服务器端
    import socket                         # 和socket客户端 一毛一样
    ip_port = ("127.0.0.1",9999)
    
    sk = socket.socket()
    sk.connect(ip_port)
    
    while True:
        client_input = input(">>:").strip()
        sk.send(bytes(client_input,"utf8"))
        server_d = sk.recv(1024)
        print("服务器端说:",str(server_d,"utf8"))
    
    sk.close()
    客户端
  • 相关阅读:
    Python基础-画菱形
    Python基础-List找重复数
    celery的使用
    linux上安装git以及使用
    python解压压缩包的几种方式
    os 和shutil模块的使用方法
    C++学习网站总结
    道德经
    使用BeautifulSoup爬取汽车之家新闻
    RPA项目所遇知识点
  • 原文地址:https://www.cnblogs.com/Vera-y/p/9936992.html
Copyright © 2011-2022 走看看