zoukankan      html  css  js  c++  java
  • 基于select的网络IO模型

    #select  和    poll    和epoll的区别
        '''
          select和poll有一个共同的机制,都是采用轮训的方式去询问内核,有没有数据准备好了
          select有一个最大监听事件的限制,32位机限制1024,,6位机限制2048
          poll没有,理论上poll可以开启无限大,1G内存大概够你开10W个事件去监听
          epoll是最好的,采用的是回调机制,解决了select和poll共同存在的问题
          而且epoll理论上也可以开启无限多个监听事件
        '''
    
    # IO多路复用
        '''
            阻塞IO
            非阻塞IO
            多路复用IO
            异步IO python实现不了,但是有tornado框架,天生自带异步
        '''
    
    #服务器端
    import socket
    import select
    
    sk=socket.socket()
    sk.bind(('127.0.0.1',8080))
    sk.listen()
    
    Conn_Del = []        #定义删除列表
    rlist = [sk]         #是用来让select帮忙监听的所有接口
    # select:windows/linux是监听事件有没有数据到来
    # poll:  linux   也可以做select的工作
    # epoll: linux   也可以做类似的工作
    
    while 1:
        r,w,x = select.select(rlist,[],[])  #将rlist传给select,当rlist中哪个接口有反应,就返回给r这个列表
        if r:
            for i in r:                     #循环遍历,看看有反应的接口是sk还是conn,因为如果是sk,后面会把conn也加到这个列表中
                if i == sk:
                    #如果是sk,表明有客户端的连接请求
                    conn,addr = i.accept()
                    rlist.append(conn)      #把新的客户端的连接,添加到rlist,继续让select帮忙监听
                else:
                    #如果是conn,代表客户端请求发送数据了(此时客户端已经连接上了)
                    #下面的异常处理模型和非阻塞IO模型解决阻塞IO模型类似
                    try:
                        msg = i.recv(1024).decode('utf-8')
                        if not msg:
                            #客户端正常关闭返回给服务器端一个空,即客户端执行了close()
                            Conn_Del.append(i)
                            i.close()
                        else:
                            #服务器端的逻辑层(以字符串大写的形式返回给客户端)
                            print("接收到来自{}客户端的消息{}".format(i,msg))
                            i.send(msg.upper().encode('utf-8'))
                    except ConnectionResetError:
                        #客户端强制关闭
                        pass
    
            if Conn_Del:
                for conn in Conn_Del:
                    rlist.remove(conn)
                Conn_Del.clear()
    
    
    sk.close()
    
    
    
    
    #客户端
    import socket
    sk = socket.socket()
    sk.connect(('127.0.0.1',8080))
    
    while 1:
        msg_s = input('>>>')
        if not msg_s:continue
        if msg_s == 'q':break
        sk.send(msg_s.encode('utf-8'))
        print(sk.recv(1024).decode('utf-8'))
    sk.close()
  • 相关阅读:
    正则
    cookie、sesion
    POJ-1509
    HDU-3374
    ZOJ-3822
    HDU-5492
    在什么情况下Java比C++快?
    HDU-5451
    SPOJ-913
    莫比乌斯反演入门
  • 原文地址:https://www.cnblogs.com/god-for-speed/p/11719114.html
Copyright © 2011-2022 走看看