一下代码,是摘自大王的博客,(http://www.cnblogs.com/alex3714/)我自己有加了些注释。

1
2
3 #_*_coding:utf-8_*_
4
5 __author__ = 'Alex Li'
6
7 import select
8 import socket
9 import sys
10 import queue
11
12 # Create a TCP/IP socket
13 server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
14 #创建一个socket,作用和文件描述符差不多(基于linux一切皆文件的哲学思想),recv相当于read(),send相当于write()。默认socket.socket默认就是加socket.AF_INET, socket.SOCK_STREAM这两个参数。
15 server.setblocking(False)
16 #sk.setblocking(bool) 是否阻塞(默认True),如果设置False,那么accept和recv时一旦无数据,则报错。accept和recv默认是阻塞的。
17
18 # Bind the socket to the port
19 server_address = ('localhost', 10000)
20 print(sys.stderr, 'starting up on %s port %s' % server_address)
21 server.bind(server_address)
22
23 # Listen for incoming connections
24 server.listen(5)
25 #理论上监听队列的长度(backlog)就是取listen和maxconn(系统层次的限定值)的最小值()
#如果客户端没有被处理的请求数超过了这个值,或者请求了一个没有侦听的端口就会报(socket.error: [Errno 10061] )
# 5,表示内核已经接到了连接请求,但服务器还没有调用accept进行处理的连接个数最大为5
这个值不能无限大,因为要在内核中维护连接队列
26
27 # Sockets from which we expect to read
28 inputs = [ server ]
29
30 # Sockets to which we expect to write
31 outputs = [ ]
32
33 message_queues = {}
34 while inputs:
35
36 # Wait for at least one of the sockets to be ready for processing
37 print( '\nwaiting for the next event')
38 readable, writable, exceptional = select.select(inputs, outputs, inputs)
39 # Handle inputs
40 for s in readable:
41
42 if s is server:
43 # A "readable" server socket is ready to accept a connection
44 connection, client_address = s.accept()
45 print('new connection from', client_address)
46 connection.setblocking(False)
47 #将这个socket设置成非阻塞的。这个socket的recv和accept就不会阻塞了。
48 inputs.append(connection)
49
50 # Give the connection a queue for data we want to send
51 message_queues[connection] = queue.Queue()
52 #创建一个字典的key和value,value就是一个队列的实例。
53 else:
54 data = s.recv(1024)
55 if data:
56 # A readable client socket has data
57 print(sys.stderr, 'received "%s" from %s' % (data, s.getpeername()) )
58 message_queues[s].put(data)
59 # Add output channel for response
60 if s not in outputs:
61 outputs.append(s)
62 else:
63 # Interpret empty result as closed connection
64 print('closing', client_address, 'after reading no data')
65 # Stop listening for input on the connection
66 if s in outputs:
67 outputs.remove(s) #既然客户端都断开了,我就不用再给它返回数据了,所以这时候如果这个客户端的连接对象还在outputs列表中,就把它删掉
68 inputs.remove(s) #inputs中也删除掉
69 s.close() #把这个连接关闭掉
70
71 # Remove message queue
72 del message_queues[s]
73 # Handle outputs
74 for s in writable:
75 try:
76 next_msg = message_queues[s].get_nowait()
77 """get_nowait:Remove and return an item from the queue without blocking.
78
79 Only get an item if one is immediately available. Otherwise
80 raise the Empty exception.
81 """
82 except queue.Empty:
83 # No messages waiting so stop checking for writability.
84 print('output queue for', s.getpeername(), 'is empty')
85 #getpeername()返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。
86 outputs.remove(s)
87 else:
88 print( 'sending "%s" to %s' % (next_msg, s.getpeername()))
89 s.send(next_msg)
90 # Handle "exceptional conditions"
91 for s in exceptional:
92 print('handling exceptional condition for', s.getpeername() )
93 # Stop listening for input on the connection
94 inputs.remove(s)
95 if s in outputs:
96 outputs.remove(s)
97 s.close()
98
99 # Remove message queue
100 del message_queues[s]

view code

io多路复用,select,笔记的更多相关文章

  1. 第五十五节,IO多路复用select模块加socket模块,伪多线并发

    IO多路复用select模块加socket模块,伪多线并发,并不是真正的多线程并发,实际通过循环等待还是一个一个处理的 IO多路复用,lo就是文件或数据的输入输出,IO多路复用就是可以多用户操作 IO ...

  2. Linux IO多路复用 select

    Linux IO多路复用 select 之前曾经写过简单的服务器,服务器是用多线程阻塞,客户端每一帧是用非阻塞实现的 后来发现select可以用来多路IO复用,就是说可以把服务器这么多线程放在一个线程 ...

  3. io多路复用-select()

    参照<Unix网络编程>相关章节内容,实现了一个简单的单线程IO多路复用服务器与客户端. 普通迭代服务器,由于执行recvfrom则会发生阻塞,直到客户端发送数据并正确接收后才能够返回,一 ...

  4. 转一贴,今天实在写累了,也看累了--【Python异步非阻塞IO多路复用Select/Poll/Epoll使用】

    下面这篇,原理理解了, 再结合 这一周来的心得体会,整个框架就差不多了... http://www.haiyun.me/archives/1056.html 有许多封装好的异步非阻塞IO多路复用框架, ...

  5. Python实战之IO多路复用select的详细简单练习

    IO多路复用 I/O多路复用指:通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作. select   它通过一个select()系统调用来 ...

  6. I/O模型系列之五:IO多路复用 select、poll、epoll

    IO多路复用之select.poll.epoll IO多路复用:通过一种机制,一个进程可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作. 应用:适用于针 ...

  7. IO多路复用select/poll/epoll详解以及在Python中的应用

    IO multiplexing(IO多路复用) IO多路复用,有些地方称之为event driven IO(事件驱动IO). 它的好处在于单个进程可以处理多个网络IO请求.select/epoll这两 ...

  8. IO多路复用 select、poll、epoll

    什么是IO多路复用 在同一个线程里面, 通过拨开关的方式,来同时传输多个(socket)I/O流. 在英文中叫I/O multiplexing.这里面的 multiplexing 指的其实是在单个线程 ...

  9. Python异步非阻塞IO多路复用Select/Poll/Epoll使用,线程,进程,协程

    1.使用select模拟socketserver伪并发处理客户端请求,代码如下: import socket import select sk = socket.socket() sk.bind((' ...

  10. 网络编程socket 结合IO多路复用select; epool机制分别实现单线程并发TCP服务器

    select版-TCP服务器 1. select 原理 在多路复用的模型中,比较常用的有select模型和epoll模型.这两个都是系统接口,由操作系统提供.当然,Python的select模块进行了 ...

随机推荐

  1. loadrunner 功能详解(一) - Run-time Settings

    1.General / Run Logic  Number of Iterations:说明的是反复循环的次数. 常境的时间中,如果时间设为5分钟,而实际上程序的运行只需要1分钟,而在这项中,选择的是 ...

  2. Linux 本人常用到的基本命令

    cat -n FileName //查看FileName文件的内容.-n显示对应行号. yum install SoftName //安装软件,切记使用root权限. service //查看服务.例 ...

  3. lua 高级

    io操作: io.input(filename):指定一个输入流,可以是标准输入stdin,也可以是一个文件路径,返回一个文件句柄: io.output(filename):指定一个输出流,可以是标准 ...

  4. js复制input 框中的值

    function copy(){ var Url2=document.getElementById("copyValue"); Url2.select(); document.ex ...

  5. phpexcel简单用法

    <?php /*php生成excel完整实例代码现求:php生成excel完整实例代码最好能说明如何调用!谢谢java_sunhui4 | 浏览 8131 次 2014-09-24 14:502 ...

  6. 將後台的Json數據返回到前台

    前台JS代碼 $.post('/Book/GetBookClassIDByName', { BookName: "旅遊手冊" }, function (data) { if (da ...

  7. 开发中model,entity和pojo的区别

    Entity接近原始数据,Model接近业务对象- Entity:是专用于EF的对数据库表的操作, Model:是为页面提供数据和数据校验的,所以两者可以并存 POJO:POJO是Plain Ordi ...

  8. [Tomcat 源码分析系列] (附件) : catalina.bat 脚本

    摘自 apache-tomcat-8.0.39-src 源码包中的 catalina.bat 脚本内容 @echo off rem Licensed to the Apache Software Fo ...

  9. sql基础知识(新手必备)

    一.简单查询 1.查询所有数据,查询部分列数据,列别名 SELECT * FROM 表名 SELECT 列1 AS 'BIAOTI1','BIAOTI2'=列2  FROM 表名 2.查询不重复的数据 ...

  10. java时间相减(转载)

    package com.jie.java.phone; import java.text.ParseException; import java.text.SimpleDateFormat; impo ...