美文网首页程序员
python 并发服务器 面向连接 多进程 多线程 单进程

python 并发服务器 面向连接 多进程 多线程 单进程

作者: L_Leisure | 来源:发表于2018-12-14 21:33 被阅读3次

    面向连接的并发服务器

    def main():
        # 1. 创建socket套接字
        tcp_server = socket(AF_INET, SOCK_STREAM)
        # 2. 绑定IP地址和端口
        tcp_server.bind(("", 8888))
        # 3. 把主动模式变成被动模式 只能接收 不能发送数据
        tcp_server.listen(5)
        while True:
            # 4. 等待客户端连接
            new_socket, client_info = tcp_server.accept()
            print(f"新的客户端来了 {client_info}")
            # 5. 接收数据
            raw_data = new_socket.recv(1024)
            while raw_data:
                print(f"收到{client_info}数据: {raw_data}")
                # 再次取
                raw_data = new_socket.recv(1024)
            # 6.关闭新套接字
            new_socket.close()
    
    
    if __name__ == '__main__':
        main()
    
    

    只能同时为一个人服务

    多进程并发服务器

    from socket import *
    from multiprocessing import Process
    
    
    def rec_data(client_info, new_socket):
        """新套接字处理数据"""
        raw_data = new_socket.recv(1024)
        while raw_data:
            print(f"收到{client_info}数据: {raw_data}")
            # 再次取
            raw_data = new_socket.recv(1024)
        # 关闭套接字
        new_socket.close()
    
    
    def main():
        # 1. 创建socket套接字
        tcp_server = socket(AF_INET, SOCK_STREAM)
        # 2. 绑定IP地址和端口
        tcp_server.bind(("", 7777))
        # 3. 把主动模式变成被动模式 只能接收 不能发送数据
        tcp_server.listen(5)
        while True:
            # 4. 等待客户端连接
            new_socket, client_info = tcp_server.accept()
            print(f"新的客户端来了 {client_info}")
            # 5. 接收数据
            # rec_data(client_info, new_socket)
            # 6.创建新的进程
            p = Process(target=rec_data, args=(client_info, new_socket))
            # 6.1 启动进程
            p.start()
            # 6.关闭新套接字 多进程必需关闭new_socket  因为会复制出来一个新的
            new_socket.close()
    
    
    if __name__ == '__main__':
        main()
    
    

    多进程服务器代表:Apache服务器

    主进程中必需关闭new_socket.close()

    多线程并发服务器

    from socket import *
    from threading import Thread
    
    
    def rec_data(client_info, new_socket):
        """新套接字处理数据"""
        raw_data = new_socket.recv(1024)
        while raw_data:
            print(f"收到{client_info}数据: {raw_data}")
            # 再次取
            raw_data = new_socket.recv(1024)
        # 关闭套接字
        new_socket.close()
    
    
    def main():
        # 1. 创建socket套接字
        tcp_server = socket(AF_INET, SOCK_STREAM)
        # 2. 绑定IP地址和端口
        tcp_server.bind(("", 7788))
        # 3. 把主动模式变成被动模式 只能接收 不能发送数据
        tcp_server.listen(5)
        while True:
            # 4. 等待客户端连接
            new_socket, client_info = tcp_server.accept()
            print(f"新的客户端来了 {client_info}")
            # 5. 接收数据
            # rec_data(client_info, new_socket)
            # 6.创建新的进程
            p = Thread(target=rec_data, args=(client_info, new_socket))
            # 6.1 启动进程
            p.start()
            # 6.关闭新套接字
            #new_socket.close()
    
    
    if __name__ == '__main__':
        main()
    
    

    多线程代表:IIS服务器

    子线程共享主线程的变量,所以主线程中不能关闭new_socket.close(),否则子线程也会断开连接

    单进程非阻塞版并发服务器

    from socket import *
    
    
    def main():
        # 1. 创建socket套接字
        tcp_server = socket(AF_INET, SOCK_STREAM)
        # 2. 把套接字设置成非阻塞
        tcp_server.setblocking(False)
        # 2. 绑定IP地址和端口
        tcp_server.bind(("", 6667))
        # 3. 把主动模式变成被动模式 只能接收 不能发送数据
        tcp_server.listen(5)
        # 4. 声明一个列表用来存新的套接字
        socket_lists = []
        while True:
            try:
                # 4. 等待客户端连接
                new_socket, client_info = tcp_server.accept()
                # 4.1 设置new_socket为非阻塞
                new_socket.setblocking(False)
            except:
                pass
            else:
                """已经有人连接,取到数据了"""
                # 把新的套接字往列表里扔
                socket_lists.append((new_socket, client_info))
                print(f"新的客户端来了 {client_info}")
    
            # 循环列表
            for sock, client_info in socket_lists:
                try:
                    # 让每一个new_socket去接收数据 又阻塞了,应该在创建new_socket后设置新的套接字为 非阻塞
                    raw_data = sock.recv(1024)
                except:
                    pass
                else:
                    # 当客户端断开的时候 raw_data 就是空
                    if raw_data:
                        print(f"收到{client_info}数据:{raw_data.decode('gb2312')}")
                    else:
                        # 客户端断了
                        sock.close()
                        # 列表移除
                        socket_lists.remove((sock, client_info))
    
    
    if __name__ == '__main__':
        main()
    
    

    相关文章

      网友评论

        本文标题:python 并发服务器 面向连接 多进程 多线程 单进程

        本文链接:https://www.haomeiwen.com/subject/fvynhqtx.html