【select模块】select IO多路复用和select实现FTP

select是全平台通用的IO多路复用模块。最大连接数:1024。

poll和epoll没有最大连接数限制,但只能用在linux平台。

selectors是再封装模块,推荐使用。下篇会讨论。

select.select(rlist, wlist, xlist[, timeout])?

  • This is a straightforward interface to the Unix select() system call. The first three arguments are sequences of ‘waitable objects’: either integers representing file descriptors or objects with a parameterless method named fileno() returning such an integer:

    Empty sequences are allowed, but acceptance of three empty sequences is platform-dependent. (It is known to work on Unix but not on Windows.)  The optional timeout argument specifies a time-out as a floating point number in seconds.  When the timeout argument is omitted the function blocks until at least one file descriptor is ready.  A time-out value of zero specifies a poll and never blocks.

    The return value is a triple of lists of objects that are ready: subsets of the first three arguments.  When the time-out is reached without a file descriptor becoming ready, three empty lists are returned.

    Among the acceptable object types in the sequences are Python file objects (e.g. sys.stdin, or objects returned by open() or os.popen()), socket objects returned by socket.socket().  You may also define a wrapper class yourself, as long as it

    • rlist: wait until ready for reading
    • wlist: wait until ready for writing
    • xlist: wait for an “exceptional condition” (see the manual page for what your system considers such a condition)
方法、属性 参数 作用 示例
select(rlist,wlist,rlist,[timout=1])
poll() 没人用了,已经升级为epoll
epoll(sizehint = -1,flags=0)
sizehint informs epoll about the expected number of events to be registered.  It must be positive, or-1to use the default. It is only used on older systems where epoll_create1() is not available; otherwise it has no effect (though its value is still checked).

flags is deprecated and completely ignored.  However, when supplied, its value must be 0 or select.EPOLL_CLOEXEC, otherwise OSError is raised.

(Only supported on Linux 2.5.44 and newer.) Return an edge polling object, which can be used as Edge or Level Triggered interface for I/O events.
devpoll() (Only supported on Solaris and derivatives.)  Returns a /dev/poll polling object; see section /dev/poll Polling Objects below for the methods supported by devpoll objects.
kevent() select.kevent(ident, filter=KQ_FILTER_READ, flags=KQ_EV_ADD, fflags=0, data=0, udata=0)?

  • (Only supported on BSD.)  Returns a kernel event object; see section Kevent Objects below for the methods supported by kevent objects.

kqueue() (Only supported on BSD.)  Returns a kernel queue object; see section Kqueue Objects below for the methods supported by kqueue objects.
import socket
import os
import select
import queue
import json

class SelectFTP(object):
    def __init__(self, ip, port):
        self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server.setblocking(0)
        self.server.bind((ip, port))
        self.server.listen(20)
        

        self.inputs = [self.server]
        self.outputs = []
        self.file_attr = {}
        # file_attr format:file_attr[socket]:{func:'', filename:'', len:999, recv_len:0}      
        self.socket_queue = {}

    
    def upload(self, sock, write_data):
        # if os.path.isfile(self.file_attr[sock]['filename']):
        with open(self.file_attr[sock]['filename'], 'a+') as file:
            file.write(data)
            self.file_attr[sock][recv_len] += len(write_data)
            if self.file_attr[sock][recv_len] == self.file_attr[sock][len]:
                del self.file_attr[sock]
                file.close()
        
   
    def download(self, sock, *args):
        pass
        
    def run(self):
        while self.inputs:
            read_active, read_output, exception = select.select(self.inputs, self.outputs, self.inputs)
            
            for fd in read_active:
                if fd is server:
                    conn, addr = fd.accept(1024)
                    conn.setblocking(0)
                    self.inputs = self.inputs.append(conn)
                    self.socket_queue[fd] = queue.Queue()
                    
                else:
                    recv_data = fd.recv(1024)

                    if recv_data:
                        data = json.loads(recv_data.decode())
                        
                        if fd not in self.file_attr.keys:
                            self.file_attr[fd] = data
                        
                        else:
                            try:
                                self.socket_queue.put_nowait(data)
                                if fd not in self.outputs:
                                    self.outputs.append(fd)
                            except Exception as e:
                                print(e)
                            
                    else:
                        self.inputs.remove(fd)
                        if fd in self.outputs:
                            self.outputs.remove(fd)
                        del self.socket_queue[fd]
                        
                    send_data = 
                        
            for fd in read_output:
                try:
                    message = self.socket_queue.get_nowait()
                except queue.Empty:
                    self.outputs.remove(fd)
                    print('wait...')
                else:
                    getattr(self.file_attr[fd]['func'])(fd, message)

原文地址:http://blog.51cto.com/yishi/2150318

时间: 2024-11-10 15:18:46

【select模块】select IO多路复用和select实现FTP的相关文章

Python-基于socket和select模块实现IO多路复用

'''IO指的是输入输出,一部分指的是文件操作,还有一部分网络传输操作,例如soekct就是其中之一:多路复用指的是利用一种机制,同时使用多个IO,例如同时监听多个文件句柄(socket对象一旦传送或者接收信息),一旦文件句柄出现变化就会立刻感知到'''1.下面通过IO多路复用实现多人同时连接socket服务器 import socket sk1 = socket.socket()#sk1,sk2,sk3这就是一个文件描述符 sk1.bind(('127.0.0.1',8002)) sk1.li

Python——IO多路复用之select模块epoll方法

Python——IO多路复用之select模块epoll方法 使用epoll方法实现IO多路复用,使用方法基本与poll方法一致,epoll效率要高于select和poll. .├── epoll_client.py├── epoll_server.py└── settings.py # settings.py HOST = 'localhost' PORT = 5555 buffersize = 1024 ADDR = HOST, PORT # poll_server.py from sett

python IO多路复用之select

说起IO操作我们最先想到的就是读写文件.其实python中对有三种IO操作,打开文件,使用socket进行网络连接和系统的标准输入输出sys.stdin和sys.stdout.我们先来看一段socket服务端的代码: import socket ip_port = ('127.0.0.1',9999) sk = socket.socket() sk.bind(ip_port) sk.listen(5) while True:     """     程序运行到accept()

网络通信 --> IO多路复用之select、poll、epoll详解

IO多路复用之select.poll.epoll详解 目前支持I/O多路复用的系统调用有 select,pselect,poll,epoll,I/O多路复用就是通过一种机制,一个进程可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作.但select,pselect,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的,而异步I/O则无需自己负责进行读写,异步I/O的实现会负责把数据从内

IO多路复用之select

基本概念 IO多路复用是指内核(线性扫描)一旦发现进程指定的一个或者多个IO条件准备就绪,它就通知该进程,执行定义的操作. 适用场景 1.当客户处理多个描述符时(一般是交互式输入和网络套接字),必须使用I/O复用. 2.当一个客户同时处理多个套接字时,而这种情况是可能的,但很少出现. 3.如果一个TCP服务器既要处理监听套接字,又要处理已连接套接字,一般也要用到I/O复用. 4.如果一个服务器即要处理TCP,又要处理UDP,一般要使用I/O复用. 5.如果一个服务器要处理多个服务或多个协议,一般

IO多路复用之select总结

1.基本概念 IO多路复用是指内核一旦发现进程指定的一个或者多个IO条件准备读取,它就通知该进程.IO多路复用适用如下场合: (1)当客户处理多个描述字时(一般是交互式输入和网络套接口),必须使用I/O复用. (2)当一个客户同时处理多个套接口时,而这种情况是可能的,但很少出现. (3)如果一个TCP服务器既要处理监听套接口,又要处理已连接套接口,一般也要用到I/O复用. (4)如果一个服务器即要处理TCP,又要处理UDP,一般要使用I/O复用. (5)如果一个服务器要处理多个服务或多个协议,一

IO多路复用:select、poll、epoll示例

一.IO多路复用 所谓IO多路复用,就是通过一种机制,一个进程可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作. Linux支持IO多路复用的系统调用有select.poll.epoll,这些调用都是内核级别的.但select.poll.epoll本质上都是同步I/O,先是block住等待就绪的socket,再是block住将数据从内核拷贝到用户内存. 当然select.poll.epoll之间也是有区别的,如下表: \ select poll e

聊聊IO多路复用之select、poll、epoll详解

IO多路复用是指内核一旦发现进程指定的一个或者多个IO条件准备读取,它就通知该进程.IO多路复用适用如下场合: 当客户处理多个描述符时(一般是交互式输入和网络套接口),必须使用I/O复用. 当一个客户同时处理多个套接口时,而这种情况是可能的,但很少出现. 如果一个TCP服务器既要处理监听套接口,又要处理已连接套接口,一般也要用到I/O复用. 如果一个服务器即要处理TCP,又要处理UDP,一般要使用I/O复用. 如果一个服务器要处理多个服务或多个协议,一般要使用I/O复用. 与多进程和多线程技术相

IO多路复用,select、poll、epoll 编程主要步骤

body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gray; border-width: 2px 0 2px 0;} th{border: 1px solid gray; padding: 4px; background-color: #DDD;} td{border: 1px solid gray; padding: 4px;} tr:nth-chil