美文网首页程序员
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