• 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)

  • 相关阅读:
    Python学习笔记_从CSV读取数据写入Excel文件中
    Python学习笔记_Python向Excel写入数据
    Python学习笔记_一个Tkinter示例,使用FileDialog
    Python学习笔记_我的参考网址
    Python读取CSV文件,报错:UnicodeDecodeError: 'gbk' codec can't decode byte 0xa7 in position 727: illegal multibyte sequence
    Python读取CSV文件
    JS写的多级联select,如何取值
    c#常用的Datable转换为json,以及json转换为DataTable操作方法
    C# 读写App.config
    一个简单的存储过程使用事务的例子
  • 原文地址:https://www.cnblogs.com/dasheng-maritime/p/14902845.html
Copyright © 2020-2023  润新知