• (四)socketserver模块


    一、前言


    虽说用 Python编写简单的网络程序很方便,但复杂一点的网络程序还是用现成的框架比较好。这样就可以专心事务逻辑,而不是套接字的各种细节。SocketServer模块简化了编写网络服务程序的任务。同时 SocketServer模块也是 Python标准库中很多服务器框架的基础。

    socketserver模块可以简化网络服务器的编写,Python把网络服务抽象成两个主要的类,一个是 Server类,用于处理连接相关的网络操作,另外一个则是 RequestHandler类,用于处理数据相关的操作。并且提供两个 MixIn 类,用于扩展 Server,实现多进程或多线程。

    二、Server类


    它包含了五种 server类,BaseServer(不直接对外服务)。TCPServer使用TCP协议,UDPServer使用UDP协议,还有两个不常使用的,即 UnixStreamServer和 UnixDatagramServer,这两个类仅仅在 unix环境下有用(AF_unix)。

    三、RequestHandler类


    所有 requestHandler都继承 BaseRequestHandler基类。

    四、创建一个 socketserver的步骤


    1,First, you must create a request handler class by subclassing the BaseRequestHandlerclass and overriding its handle() method; this method will process incoming requests. 

    2,Second, you must instantiate one of the server classes, passing it the server’s address and the request handler class.

    3,Then call the handle_request() orserve_forever() method of the server object to process one or many requests.

    4,Finally, call server_close() to close the socket.

    # socketserver 的使用模式:固定4步
    """
    1,先创建一个类(自定义功能类),继承的父类是固定的,下面定义一个handle方法,方法名handle固定的
    class Myserver(socketserver.BaseRequestHandler):
        def handle(self):   
            pass
    
    2,通过 socketserver去引一个咱们要并发的类,初始化一个对象
    server = socketserver.ThreadingTCPServer(("192.168.2.209",8800),Myserver)
    
    
    3,把初始化的对象调用一个方法 serve_forver()
    server.serve_forever()

    4,server.server_close()
    """

    五、流程图


    如下流程图:

    六、单线程示例


    server端:

    from socket import *
    
    server = socket(AF_INET, SOCK_STREAM)
    server.bind(("192.168.2.209",8800))
    server.listen(5)
    
    while True:
        conn, addr = server.accept()
        print("客户端:",addr)
        while True:
            try:
                client_data = conn.recv(1024)
                if not client_data: continue
                conn.send(client_data.upper())
            except ConnectionResetError:
                break
        conn.close()
    
    server.close()

    client端:

    from socket import *
    
    client = socket(AF_INET,SOCK_STREAM)
    client.connect(("192.168.2.209",8800))
    
    while True:
        msg = input(">>:").strip()
        if not msg:continue
        client.send(msg.encode("utf-8"))
        data = client.recv(1024)
        print("收到的数据:%s" % data.decode("utf-8"))
    
    client.close()

    七、并发示例


    server端:

    import socketserver
    
    class Myserver(socketserver.BaseRequestHandler):
        def handle(self):   # 函数名固定的
            """
            并发的业务逻辑
            conn套接字变成了,self.request(固定的)
            :return:
            """
            while True:
                try:
                    client_data = self.request.recv(1024)
                    if not client_data: continue
                    self.request.send(client_data.upper())
                except ConnectionResetError:
                    break
            self.request.close()
    
    # 这段代码做了几件事情:1)创建了一个套接字对象self.socket。2)进行绑定self.socket.bind()。3)挂起的最大数self.socket.listen()
    server = socketserver.ThreadingTCPServer(("192.168.2.209",8800),Myserver)       # 这个类利用了 Python的混合继承
    # ThreadingTCPServer 是多进程,ForkingTCPServer 是多线程
    
    server.serve_forever()
    server.server_close()

    client端:

    与单线程一样,不用改。

  • 相关阅读:
    根据W3C总结Ajax基础技术
    MVC中ActionName标记属性的用法
    为什么做网站一般不用服务端控件?
    Jquery两个比较常用的方法each和data
    MVC中的路由
    SQL中获取刚插入记录时对应的自增列的值
    第一个文章,今天比较兴奋啊! 给大家一个关于SQL复合查询的文章(动态生成多个where条件)
    获取 汉字的首字母(例如张三返回zs)核心方法chinesecap()
    ASP.NET中判断密码的安全度(低,中,高)
    C# 关于密码加密 (转载)
  • 原文地址:https://www.cnblogs.com/zoling7/p/13405712.html
Copyright © 2020-2023  润新知