# can_read, can_write, _ = select.select(inputs, outputs, None, None)
#
# 第一个参数是我们需要监听可读的套接字, 第二个参数是我们需要监听可写的套接字, 第三个参数使我们需要监听异常的套接字, 第四个则是时间限制设置.
#
# 如果监听的套接字满足了可读可写条件, 那么所返回的can,read 或是 can_write就会有值了, 然后我们就可以利用这些返回值进行随后的操作了。相比较unix 的select模型, 其select函数的返回值是一个整型, 用以判断是否执行成功.
#
# 第一个参数就是服务器端的socket, 第二个是我们在运行过程中存储的客户端的socket, 第三个存储错误信息。
# 重点是在返回值, 第一个返回的是可读的list, 第二个存储的是可写的list, 第三个存储的是错误信息的
# list。
import select, socket, queue
from time import sleep

# 创造一个 TCP/IP连接
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 设置socket为异步模式。
server.setblocking(False)

# 绑定IP地址和端口
# 创建一个IP,端口,本地IP
server_address = ('localhost', 8090)
print('starting up on %s port %s' % server_address)
# 绑定IP和端口
server.bind(server_address)

# 设置服务端监听数量
server.listen(3)
inputs = [server]
# 处理要发送的数据
outputs = []

# 输出的消息队列
message_queues = {}

while inputs:
# 等待至少一个连接开始调用线程
print("waiting for the next event")
# 开始select监听,对input_list中的服务器端的server开始进行监听
# 一旦调用socket的send,recv函数,将会再次调用此模块
# 这里监控三个参数,第一个返回的是可读的list, 第二个存储的是可写的list, 第三个存储的是错误信息的
readable, writable, exceptional = select.select(inputs, outputs, inputs)

# 处理输入
# 循环判断是否有客户端连接进来,当有客户端连接进来的时候select将进行触发
for s in readable:
# 判断当前触发的是不是服务端对象,当触发的是服务端对象, 说明有新的客户端连接进来了
if s is server:
# 和客户端建立连接
connection, client_address = s.accept()
# 打印客户端的链接
print('connection from', client_address)
# 设置socket为异步模式。
connection.setblocking(0)
# 将客户端对象也加入到监听列表中,当客户端发送消息的时候select也会触发。
inputs.append(connection)

# 为连接的客户端单独建立一个消息队列,用来保存客户端发送的消息
message_queues[connection] = queue.Queue()
else:
# 有老用户发送消息,处理接收
# 由于客户端连接进来的时候服务端接收客户端的请求,将客户端也加入到了监听列表。
# 客户端发送的消息将触发。
# 判断触发对象是否为客户端
# 接收客户端的信息
data = s.recv(1024)
# 客户端没有断开
if data != '':
# 一个可用的客户端发送了数据
print('received "%s" from %s' % (data, s.getpeername()))
# 将接受到的消息放到对应的客户端的消息队列中
message_queues[s].put(data)
# 将需要进行回复操作的socket放到output列表中,让select监听
# 这里我们如果收到消息将服务端添加进入输出列表。
# 然后select就会监听到,
if s not in outputs:
outputs.append(s)
else:
# 客户端被监听到有变化,不是有客户端传过来的消息,就是客户端断开了。
# 客户端断开了连接,将客户端的监听从input列表中移除
print('closing', client_address)
if s in outputs:
outputs.remove(s)
inputs.remove(s)
s.close()

# 移除对应的socket客户端对象的消息队列
del message_queues[s]

# 处理输出。
# 如果现在没有客户端的请求,也没有客户端发送消息时,开始对发送的消息列表进行处理。
# 判断是否需要发送消息。
# 存储哪个客户端发送了消息。
for s in writable:
try:
# 如果消息队列中有消息,就从消息队列中获取要发送的消息。
message_queue = message_queues.get(s)
sent_data = ''
if message_queues is not None:
# 如果队列为空的话不等(阻塞)
send_data = message_queue.get_nowait()
else:
# 客户端断开连接了
print('has closed')
# 如果队列为空的话,就代表着发送的消息完了,就需要从队列中删除。
except queue.Empty:
print('%s' % (s.getpeername()))
outputs.remove(s)
else:
# print "sending %s to %s " % (send_data, s.getpeername)
# print "send something"
if message_queue is not None:
s.send(send_data)
else:
print("has closed ")

# del message_queues[s]
# writable.remove(s)
# print "Client %s disconnected" % (client_address)

# # Handle "exceptional conditions"
# 处理异常的情况
# 如果有异常情况,那么就从输出队列中删除,然后关闭连接。
for s in exceptional:
print('exception condition on', s.getpeername())
# Stop listening for input on the connection
inputs.remove(s)
if s in outputs:
outputs.remove(s)
s.close()

# Remove message queue
del message_queues[s]

sleep(1)

select监听服务端的更多相关文章

  1. DSAPI多功能组件编程应用-HTTP监听服务端与客户端_指令版

    前面介绍了DSAPI多功能组件编程应用-HTTP监听服务端与客户端的内容,这里介绍一个适用于更高效更快速的基于HTTP监听的服务端.客户端. 在本篇,你将见到前所未有的超简化超傻瓜式的HTTP监听服务 ...

  2. DSAPI HTTP监听服务端与客户端

    本文中,演示了使用DSAPI.网络相关.HTTP监听,快速建立服务端和客户端. HTTP监听服务端的作用,是监听指定计算机端口,以实现与IIS相同的解析服务,提供客户端的网页请求,当然,这不仅仅是应用 ...

  3. DSAPI HTTP监听服务端与客户端_指令版

    前面介绍了DSAPI多功能组件编程应用-HTTP监听服务端与客户端的内容,这里介绍一个适用于更高效更快速的基于HTTP监听的服务端.客户端. 在本篇,你将见到前所未有的超简化超傻瓜式的HTTP监听服务 ...

  4. DSAPI多功能组件编程应用-HTTP监听服务端与客户端

    本文中,演示了使用DSAPI.网络相关.HTTP监听,快速建立服务端和客户端. HTTP监听服务端的作用,是监听指定计算机端口,以实现与IIS相同的解析服务,提供客户端的网页请求,当然,这不仅仅是应用 ...

  5. oracle监听服务开启

    输入命令netca即可开启oracle的监听服务 弹出对话框 选择监听服务配置,单击下一步 选择增加监听,单击下一步 监听的名字,默认即可,下一步 监听链接的协议,默认TCP协议即可,下一步 监听默认 ...

  6. oracle 监听服务配置

    最近在red hat 6.6虚拟机上安装了Oracle 11gR2数据库,安装完毕,使用没有问题,通过主机也可以访问到虚拟机上的数据库.然而,在重新启动虚拟机后,主机无法访问到数据库,提示错误: PS ...

  7. Oracle监听服务启动失败案例

    在ORACLE测试服务器上还原恢复了一个数据库后,启动监听服务时出现了TNS-12541, TNS-12560,TNS-00511之类的错误,具体情况如下所示: [oracle@getlnx01 ad ...

  8. oracle数据库没有监听服务与实例服务(OracleServicesXX)的解决方法

    不知道为什么,可能是因为更新系统的原因,过了一段时间,想打开oracle服务,发现居然没有任何oracle有关的服务了,但以前的数据库文件什么的都在,心想肯定是可以复原的,应该只是注册表的问题罢了.在 ...

  9. 服务器重启后Oracle监听服务没有自动启动的解决方案

    最近一直在被这样一个问题烦恼,就是服务器断电重启后,Oracle监听服务没有正常自动启动(监听服务已经设置为自启动). 具体是这样的,监听服务设置为开机自启动,Oracle数据库服务设置为开机延时启动 ...

随机推荐

  1. 关于LoRa安全联盟的六大常见问题

    LoRaWAN的安全机制在哪里指定? 所有安全机制都在LULA联盟规范中指定,可以由公众下载. LoRa联盟规范如何保证LoRaWAN网络的安全操作? LoRaWAN支持来源认证.完整的媒体访问控制( ...

  2. 4G DTU的应用场景介绍

    4G DTU因为信号要比传统的gprs网络要好,目前已经被广泛应用于物联网产业链中的M2M行业,以远向4G DTU LTE-520为例,它的应用场景如智能电网.智能交通.智能家居.金融.移动 POS ...

  3. nginx处理vue打包文件后的跨域问题

    起因 在vue文件打包后,项目脱离了vue配置的反向代理配置,还是会报跨域的错误,或者直接打不开本地文件, 但是此刻我们想打开打包后的文件,测试一下文件有没有错误,因为经常会存在开发阶段没有问题,打包 ...

  4. 我用 Python 找出了删除我微信的所有人并将他们自动化删除了

    1. 概述 不知你是否遇到过在微信上给通讯录中的某个人发消息,结果出现了这一幕: 平时一直认为自己的心里素质过硬,不过遇到这种情况 ... 在我缓了半个钟头(半分钟)之后,缓缓拿出了手机,打开微信,找 ...

  5. 微信小程序开发之云开发

    创建云开发小程序项目 开通云开发 开通后界面 选择开发环境 开启使用npm模块 安装wx-server-sdk npm install --save wx-server-sdk@latest 创建云函 ...

  6. JavaScript之构造函数

    在学习构造函数之前我们需要知道我们学习构造函数需要学习什么: 1.什么是构造函数  2.构造函数用来做什么 3.构造函数的执行过程  4.构造函数的返回值 1.所以首先我们需要知道什么是构造函数: 在 ...

  7. Spring笔记(7) - Spring的事件和监听机制

    一.背景 事件机制作为一种编程机制,在很多开发语言中都提供了支持,同时许多开源框架的设计中都使用了事件机制,比如SpringFramework. 在 Java 语言中,Java 的事件机制参与者有3种 ...

  8. 记在Linux上定位后台服务偶发崩溃的问题

    问题描述 在最近的后台服务中,新增将某个指令的请求数据落盘保存的功能.在具体实现时,采用成员变量来保存请求消息代理头,在接收响应以及消息管理类释放时进行销毁.测试反馈,该服务偶发崩溃. 问题分析 测试 ...

  9. ngx accept_mutex

    尝试获取锁,如果获取了锁,那么还要将当前监听端口全部注册到当前worker进程的epoll当中去  获取失败就需要确保此时ls-fd 没有被 epoll 监听 ngx_int_t ngx_tryloc ...

  10. nginx&http 第三章 ngx 1-http ngx_http_wait_request_handler

    对于活跃的 HTTP 连接,在执行连接建立回调函数 ngx_http_init_connection 的过程中会执行 ngx_http_wait_request_handler 回调函数, 负责 HT ...