美文网首页
非堵塞IO

非堵塞IO

作者: 冬至是条狗 | 来源:发表于2018-12-13 22:34 被阅读0次
    • 之前在使用socket进行数据收发的时候,进程(线程)会堵塞在accept,recv等方法,而使用非堵塞方式则会解决这类问题。下面是一个简单的非堵塞socket实例。
    server端:
    
    import socket
    
    so = socket.socket()
    so.bind(("127.0.0.1", 9999))
    so.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    so.setblocking(False)  # 设置为非堵塞IO
    so.listen()
    while True:
        try:
            conn, addr = so.accept()
            print(addr)
            mes = conn.recv(1024)
            print(mes.decode("UTF-8"))
        except BlockingIOError:
            pass
    
    
    conn.close()
    so.close()
    
    
    client端:
     import socket
    
    so = socket.socket()
    so.connect(("127.0.0.1", 9999))
    so.send(b"hello")
    so.close()
    
    • setblocking(False)是设置非堵塞IO的方法,不设置时,默认为True,当设置了这个参数为False,再调用会导致堵塞的函数则不会堵塞一直顺序执行代码,这样会导致下面的代码出现错误,这时就要使用try来捕获异常进行处理。
      下面的例子展示了使用非阻塞IO进行socket聊天:
    import socket
    
    so = socket.socket()
    so.bind(("127.0.0.1", 9999))
    so.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    so.setblocking(False)  # 设置为非堵塞IO
    so.listen()
    conn_list = []
    del_conn_list = []
    
    
    while True:
        try:  # 所有的堵塞操作都要有异常处理
            conn, addr = so.accept()
            print(addr, "已经连接了")
            conn_list.append(conn)
        except BlockingIOError:
            for conn in conn_list:
                try:  # 所有的堵塞操作都要有异常处理
                    mes = conn.recv(1024)
                    if mes == b"":  # 连接断开会发送空字符
                       # conn_list.remove(conn)  # 不能从列表删除该连接,会导致列表索引混乱
                        del_conn_list.append(conn)
                        continue
                    print("收到%s的消息:%s" % (conn.getsockname(), mes.decode("UTF-8")))
                    print("连接列表长度", len(conn_list))
                  
                except Exception:
                    pass
    
            for conn in del_conn_list:  # 这里注意,是遍历要删除列表中的项
                conn.close()  # 在这里需要Close掉连接,因为对面已经断开了
                conn_list.remove(conn)
            del_conn_list.clear()
    
    conn.close()
    so.close()
    
    • while True 会导致CPU利用率快速上升还,这是非阻塞IO的一大弊端。

    相关文章

      网友评论

          本文标题:非堵塞IO

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