zoukankan      html  css  js  c++  java
  • 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)

  • 相关阅读:
    每日一题_191101
    阿基米德三角形(交互式学件)
    2018四川高考数学(全国卷3)理科21题以泰勒公式为命题背景(同时深挖去年高考题)和它的另类解法的瞎谈
    给老谢画的图(平面几何中的动点与最值问题)
    2018四川高考文科21题
    数学解题的思维过程
    Qt Creator 模块QtSql
    QT Creator快捷键不能用
    QT 随机数
    C++ 4 种具有更 为准确语义的新强制转换类型
  • 原文地址:https://www.cnblogs.com/dasheng-maritime/p/14902845.html
Copyright © 2011-2022 走看看