异步select
server coding:
#!/usr/bin/python
# -*- coding: utf-8 -*- import select
import socket
import sys
import Queue # Create a TCP/IP socket
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.setblocking(False) # Bind the socket to the port
server_address = ('localhost',1000)
print >>sys.stderr, 'starting up on %s port %s'%server_address
server.bind(server_address) # Listen for incoming connections
server.listen(5) # Sockets from which we expect to read
inputs = [server] # Sockets to which we expect to write
outputs = [] # Outgoing message queues (socket:Queue)
message_queues = {} while True:
# Wait for at least one of the sockets to be ready for processing
print >>sys.stderr, '\nwaiting for the next event'
#分别筛选出可接收消息的sockets、等待发送消息的sockets、和中途出错的sockets。
#其中exceptional为了把所有可接收消息的sockets都遍历到,所以要从inputs列表中读取。
readable, writable, exceptional = select.select(inputs,outputs,inputs) # Handle inputs
for s in readable:
#第一种情况,创建一个待接收消息的socket放入inputs
if s is server:
# A "readable" server socket is ready to accept a connection
connection, client_address = s.accept()
print >>sys.stderr, 'new connection from', client_address
connection.setblocking(0)
inputs.append(connection) # Give the connection a queue for data we want to send
message_queues[connection] = Queue.Queue() #第二种情况,在后续循环中,已经添加到inputs中的sockets已经不是readable了,所以
#要进行接收消息,消息存在message_queues中,并把该socket添加到outputs。
else:
data = s.recv(1024)
if data:
# A readable client socket has data
print >>sys.stderr, 'receieved "%s" from %s'%(data.upper(),s.getpeername())
message_queues[s].put(data)
# Add output channel for response,添加到待发送消息列表
if s not in outputs:
outputs.append(s) #第三种情况就是这个客户端已经断开了,
#所以你再通过recv()接收到的数据就为空了,
#所以这个时候你就可以把这个跟客户端的连接关闭了。
else:
print >>sys.stderr, 'closing',client_address,'after reading no data'
if s in outputs:
outputs.remove(s)#既然客户端都断开了,我就不用再给它返回数据了,所以这时候如果这个客户端的连接对象还在outputs列表中,就把它删掉
inputs.remove(s)#inputs中也删除掉
s.close()#把这个连接关闭掉 # Remove message queue
del message_queues[s] # Handle outputs
for s2 in writable:
try:
next_msg = message_queues[s2].get_nowait()
#没有消息了
except Queue.Empty:
# No messages waiting so stop checking for writability.
print >>sys.stderr,'output queue for',s2.getpeername(),'is empty'
outputs.remove(s2)
#发送消息
else:
print >>sys.stderr, 'sending "%s" to %s'%(next_msg,s2.getpeername())
s2.send(next_msg) # Handle "exceptional conditions"
for s3 in exceptional:
print >>sys.stderr, 'handling exceptional condition for ',s3.getpeername()
# Stop listening for input on the connection
inputs.remove(s3)
if s3 in outputs:
outputs.remove(s3)
s3.close() #Remove message queue
del message_queues[s3]
client coding
# -*- coding: utf-8 -*-
"""
Created on Sun Oct 23 14:49:20 2016 @author: fuzzier
""" import sys
import socket messages = ['This is the message.',
'It will be sent',
'in parts.'
]
server_address = ('localhost',1000) # Create a TCP/IP socket,创建两个客户端
socks = [socket.socket(socket.AF_INET,socket.SOCK_STREAM),
socket.socket(socket.AF_INET,socket.SOCK_STREAM)
] # Connect the socket to the port where the server is listening
print >>sys.stderr, 'connecting to %s port %s'%server_address
for s in socks:
s.connect(server_address) for message in messages: # Send messages on both sockets
for s2 in socks:
print >>sys.stderr, '%s:sending "%s"'%(s2.getsockname(),message)
s2.send(message) #Read responses on both sockets
for s3 in socks:
data = s3.recv(1024)
print >>sys.stderr, '%s: received "%s"' % (s3.getsockname(), data.upper())
if not data:
print >>sys.stderr,'closing socket',s3.getsockname()
s3.close()
原理图:

运行结果:


异步select的更多相关文章
- linux基础编程:IO模型:阻塞/非阻塞/IO复用 同步/异步 Select/Epoll/AIO(转载)
IO概念 Linux的内核将所有外部设备都可以看做一个文件来操作.那么我们对与外部设备的操作都可以看做对文件进行操作.我们对一个文件的读写,都通过调用内核提供的系统调用:内核给我们返回一个file ...
- python 异步 select pooll epoll
概念: 首先列一下,sellect.poll.epoll三者的区别 select select最早于1983年出现在4.2BSD中,它通过一个select()系统调用来监视多个文件描述符的数组,当se ...
- 第十天 多进程、协程(multiprocessing、greenlet、gevent、gevent.monkey、select、selector)
1.多进程实现方式(类似于多线程) import multiprocessing import time,threading def thread_run():#定义一个线程函数 print(&quo ...
- IO模型与select,poll,epoll
五种:阻塞,非阻塞,IO复印,信号驱动,异步. select,poll,epoll select: 典型用32个32位的整数表示1024个描述符,并发的局限. poll:功能同上,但数据结构不一样(链 ...
- 基础10 多进程、协程(multiprocessing、greenlet、gevent、gevent.monkey、select、selector)
1.多进程实现方式(类似于多线程) import multiprocessing import time,threading def thread_run():#定义一个线程函数 print(&quo ...
- 🍛 餐厅吃饭版理解 IO 模型:阻塞 / 非阻塞 / IO 复用 / 信号驱动 / 异步
IO 概念 一个基本的 IO,它会涉及到两个系统对象,一个是调用这个 IO 的进程对象,另一个就是系统内核 (kernel).当一个 read 操作发生时,它会经历两个阶段: 通过 read 系统调用 ...
- python 开发一个支持多用户在线的FTP
### 作者介绍:* author:lzl### 博客地址:* http://www.cnblogs.com/lianzhilei/p/5813986.html### 功能实现 作业:开发一个支持多用 ...
- [NewLife.XCode]高级查询(化繁为简、分页提升性能)
NewLife.XCode是一个有10多年历史的开源数据中间件,支持nfx/netcore,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode. 整个系列教程会大量结合示例代码和 ...
- 常见网络编程面试题答案征集与面试题(收集) ZZ 【网络编程】
http://www.cnblogs.com/wickedboy237/archive/2013/05/12/3074362.html 1:tcp和udp的区别2:流量控制和拥塞控制的实现机制3:滑动 ...
随机推荐
- [LeetCode] Inorder Successor in BST 二叉搜索树中的中序后继节点
Given a binary search tree and a node in it, find the in-order successor of that node in the BST. No ...
- adb devices 偵測不到 手機
現象: system 有偵測到 mobile phone, xxx@xxx-ThinkPad-T460p:~/.android$ lsusb Bus Device : ID 1d6b: Linux F ...
- sql server生成递归日期
WITH Date AS ( SELECT CAST('2008-08-01' AS DATETIME) da UNION ALL FROM Date WHERE da < '2008-08-2 ...
- hibernate处理null 时提示:Property path [...] does notreference a collection
Hibernate判断某属性不为null 且不可为空时出现Property path [...] does notreference a collection 的问题 处理空的方法: isNotEmp ...
- Android基础总结(四)
网络图片查看器 确定图片的网址 发送http请求 URL url = new URL(address); //获取连接对象,并没有建立连接 HttpURLConnection conn = (Http ...
- ADO.NET常用对象
一.Connection对象 Connection对象也称为数据库连接对象,Connection对象的功能是负责对数据源的连接.所有Connection对象的基类都是DbConnection类. Co ...
- linux系统下使用xampp 丢失mysql root密码【xampp的初始密码为空】
如果在ubuntu 下面 使用xampp这个集成开发环境,却忘记mysql密码. 注:刚安装好的xampp的Mysql初始密码是空... 找回密码的步骤如下: 1.停止mysql服务器 sudo /o ...
- 面对bug和困难的心态
遇到bug了? 作为程序员,会面对各种各样的bug,我们在编写代码的时候,也是生产bug的过程.在公司总会遇到老同事留下的代码,这些代码出现问题了该怎么办?最常见的想法就是, 老同事怎么考虑这么不周到 ...
- Windows下安装Oracle拖慢开机速度的解决方法
环境:win7 + oracle R2 方法:将安装Oracle后自动开机启动的服务改为手动启动 步骤如下: 1.修改服务项 Ctrl + R,输入services.msc,打开服务列表,找到Orac ...
- 3. web前端开发分享-css,js提高篇
一. css基础知识掌握之后(个人的标准是:弄清块元素与内联元素的区别,弄清float的应用场景,弄清position[pə'zɪʃən] 下五个属性static['stætɪk],relative[ ...