zoukankan      html  css  js  c++  java
  • IO多路复用

    #

    IO多路复用
    操作系统提供给你的
    对于你的程序来说 : 是一个代理
    帮助你监听所有的通信对象,是否有数据来到操作系统中
    一旦有 就通知你
    你再根据通知来接收相应的数据
    你不需要一直循环着问每一个对象是否有信息来,而是阻塞等待,任意一个对象有信息来,我就接收
    IO多路复用
    io多路复用有好几种机制 : select poll epoll
    多个io对象,多个conn,sk
    一个conn占着一条网络连接的路
    多个conn占着多条路
    多个conn复用同一个线程的操作
    机制
    from socket import *
    import select
    s=socket(AF_INET,SOCK_STREAM) #允许端口重用
    s.bind(('127.0.0.1',8081))
    s.listen(5)
    s.setblocking(False) #设置socket的接口为非阻塞
    read_l=[s,]
    while True:
        r_l,w_l,x_l=select.select(read_l,[],[]) #监听对象的读事件
        print(r_l,read_l)
        for ready_obj in r_l: #
            if ready_obj == s: #sk
                conn,addr=ready_obj.accept() #此时的ready_obj等于s
                read_l.append(conn) #链接
            else:
                try:
                    data=ready_obj.recv(1024) #此时的ready_obj等于conn
                    if not data: #主动断开链接
                        ready_obj.close() #关掉链接
                        read_l.remove(ready_obj) #删除这个conn
                        continue
                    ready_obj.send(data.upper()) #信息不为空 大写处理
                except ConnectionResetError: #操作系统差异报警
                    ready_obj.close() #关闭连接
                    read_l.remove(ready_obj) #删除
    select 所有操作系统都有 轮询机制 监听对象多越来越慢/个数有限
    vvvv
    poll 轮询 优化底层数据结构
    vvv
    epoll 不使用轮询 linux 回调函数机制 不受个数影响

    # 异步IO    就像快递直接放你座位上

    vvv
    C语言能写 asyncio Python支持异步

    # selectors 模块

    #服务端
    from socket import *
    import selectors
    
    sel=selectors.DefaultSelector()
    def accept(server_fileobj,mask):
        conn,addr=server_fileobj.accept()
        sel.register(conn,selectors.EVENT_READ,read)
    
    def read(conn,mask):
        try:
            data=conn.recv(1024)
            if not data:
                print('closing',conn)
                sel.unregister(conn)
                conn.close()
                return
            conn.send(data.upper()+b'_SB')
        except Exception:
            print('closing', conn)
            sel.unregister(conn)
            conn.close()
    
    
    
    server_fileobj=socket(AF_INET,SOCK_STREAM)
    server_fileobj.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
    server_fileobj.bind(('127.0.0.1',8088))
    server_fileobj.listen(5)
    server_fileobj.setblocking(False) #设置socket的接口为非阻塞
    sel.register(server_fileobj,selectors.EVENT_READ,accept) #相当于网select的读列表里append了一个文件句柄server_fileobj,并且绑定了一个回调函数accept
    
    while True:
        events=sel.select() #检测所有的fileobj,是否有完成wait data的
        for sel_obj,mask in events:
            callback=sel_obj.data #callback=accpet
            callback(sel_obj.fileobj,mask) #accpet(server_fileobj,1)
    
    #客户端
    from socket import *
    c=socket(AF_INET,SOCK_STREAM)
    c.connect(('127.0.0.1',8088))
    
    while True:
        msg=input('>>: ')
        if not msg:continue
        c.send(msg.encode('utf-8'))
        data=c.recv(1024)
        print(data.decode('utf-8'))
    使用
    socketserver
    selectors模块 + threading模块实现的
  • 相关阅读:
    Android数据的四种存储方式SharedPreferences、SQLite、Content Provider和File (二) —— SQLite
    理解 Continuation
    99种用Racket说I love you的方式
    Racket Cheat Sheet
    scheme 教程 #lang racket
    开始学习Scheme
    MIT Scheme 的基本使用
    CPS变换
    SECD machine
    scheme 之门
  • 原文地址:https://www.cnblogs.com/zhangchen-sx/p/11037372.html
Copyright © 2011-2022 走看看