• python 实验普通IO和多路复用IO


    普通IO方式

    服务端:

    # -*- coding: utf-8 -*-
    """
    @Time    : 2021/6/19 10:12
    @Author  : xiaochao
    """
    import socket
    
    # 创建一个socket
    # socket.AF_INET 类型指明为网络连接;
    # socket.SOCK_STREAM 表示当前连接为TCP连接
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 绑定服务端,监听的端口
    server_socket.bind(("localhost", 6999))
    # 表示服务端,最多可接受5个等待的客户端连接;再多的连接请求会被拒绝
    server_socket.listen(5)
    print("Start server")
    while True:
        # 等待某个客户端的连接,如果有多个客户端连接,后到的会排队
        conn, addr = server_socket.accept()
        print("Success connect with:%s." % str(addr))
        print(conn, addr)
        # 处理对当前客户端的连接请求
        # 当前和客户端建立连接后,会一直在此处理或等待;直到对方关闭连接
        while True:
            try:
                data = conn.recv(1024)
                print("receive:", data.decode())
                msg = "hi client:%s, I am server, and I get you message." % str(addr)
                conn.send(msg.encode("utf8"))
            except (ConnectionResetError, ConnectionAbortedError) as e:
                print("当前连接已关闭,client:%s." % str(addr))
                print(str(e))
                break
        conn.close()

    客户端:

    # -*- coding: utf-8 -*-
    """
    @Time    : 2021/6/19 10:12
    @Author  : xiaochao
    """
    import socket
    import time
    
    # 创建客户端socket
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 与服务端建立连接
    client_socket.connect(("localhost", 7999))
    print("Success connect with server")
    # 模拟发送10次消息
    for i in range(10):
        time.sleep(5)
        msg = "hi server, I am client 1, message:%s." % i
        client_socket.send(msg.encode("utf8"))
        data = client_socket.recv(1024)
        print("Get server response:%s." % data.decode())
    client_socket.close()

    服务端多路复用:

    # -*- coding: utf-8 -*-
    """
    @Time    : 2021/6/19 10:12
    @Author  : xiaochao
    """
    import select
    import socket
    
    # 创建一个socket
    # socket.AF_INET 类型指明为网络连接;
    # socket.SOCK_STREAM 表示当前连接为TCP连接
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 绑定服务端,监听的端口
    server_socket.bind(("localhost", 7999))
    # 设置非阻塞方式
    server_socket.setblocking(False)
    server_socket.listen(5)
    print("Start server")
    
    inputs = [server_socket, ]
    while True:
        r_list, w_list, e_list = select.select(inputs, [], [], 3)
        for event in r_list:
            if event == server_socket:
                new_sock, addr = event.accept()
                print("Get new client:%s." % str(addr))
                inputs.append(new_sock)
            else:
                client_name = event.getpeername()
                data = event.recv(1024)
                if data:
                    print("Receive client:%s msg:%s." % (client_name, data.decode()))
                    msg = "hi client:%s, i am server." % str(client_name)
                    event.send(msg.encode("utf8"))
                else:
                    print("Connect close with client:%s." % str(client_name))
                    inputs.remove(event)

    创建两个客户端,连接多路复用的服务端,输出如下:

     

    Start server
    Get new client:('127.0.0.1', 51550).
    Receive client:('127.0.0.1', 51550) msg:hi server, I am client 1, message:0..
    Receive client:('127.0.0.1', 51550) msg:hi server, I am client 1, message:1..
    Receive client:('127.0.0.1', 51550) msg:hi server, I am client 1, message:2..
    Receive client:('127.0.0.1', 51550) msg:hi server, I am client 1, message:3..
    Get new client:('127.0.0.1', 51555).
    Receive client:('127.0.0.1', 51550) msg:hi server, I am client 1, message:4..
    Receive client:('127.0.0.1', 51555) msg:hi server, I am client 2, message:0..
    Receive client:('127.0.0.1', 51550) msg:hi server, I am client 1, message:5..
    Receive client:('127.0.0.1', 51555) msg:hi server, I am client 2, message:1..
    Receive client:('127.0.0.1', 51550) msg:hi server, I am client 1, message:6..
    Receive client:('127.0.0.1', 51555) msg:hi server, I am client 2, message:2..
    Receive client:('127.0.0.1', 51550) msg:hi server, I am client 1, message:7..
    Receive client:('127.0.0.1', 51555) msg:hi server, I am client 2, message:3..
    Receive client:('127.0.0.1', 51550) msg:hi server, I am client 1, message:8..
    Receive client:('127.0.0.1', 51555) msg:hi server, I am client 2, message:4..
    Receive client:('127.0.0.1', 51550) msg:hi server, I am client 1, message:9..
    Connect close with client:('127.0.0.1', 51550).
    Receive client:('127.0.0.1', 51555) msg:hi server, I am client 2, message:5..
    Receive client:('127.0.0.1', 51555) msg:hi server, I am client 2, message:6..
    Receive client:('127.0.0.1', 51555) msg:hi server, I am client 2, message:7..
    Receive client:('127.0.0.1', 51555) msg:hi server, I am client 2, message:8..
    Receive client:('127.0.0.1', 51555) msg:hi server, I am client 2, message:9..
    Connect close with client:('127.0.0.1', 51555).

    多路复用所带来的效果和好处,体现在以下两个方面:

    1. 用一个线程,可以监控和处理多个文件描述符;

    2. 将多个文件描述符的多次系统调用,优化为一次系统调用+内核层遍历文件描述符;

    多路复用的文章参考:

    你管这破玩意叫 IO 多路复用?_程序员小灰的博客-CSDN博客

    Python实现socket的非阻塞式编程 - 简书 (jianshu.com)

  • 相关阅读:
    IoC~MVC3+EF+Autofac实现松耦合的系统架构 [转载]
    Ioc容器Autofac系列 向导
    依赖注入框架Autofac的简单使用 转载
    学 Win32 汇编[30] 条件及循环伪指令: .IF、.WHILE、.REPEAT 等
    学 Win32 汇编[31] 结构与联合
    在 API 函数中使用 PChar 参数的几种方法
    关于 "高位" 与 "低位" 回复 "Lovemit" 的问题
    如何把类中的方法做参数 回复 "林Lin☆☆" 的问题
    一个拼图工具的制作思路 回复 "AlwaysBug" 的问题
    简单的 "双缓冲" 绘图的例子 回复 "TookiQ" 的问题
  • 原文地址:https://www.cnblogs.com/dasheng-maritime/p/14902845.html
Copyright © 2020-2023  润新知