Python网络编程使用select实现socket全双工异步通信功能示例


Posted in Python onApril 09, 2018

本文实例讲述了Python网络编程使用select实现socket全双工异步通信功能。分享给大家供大家参考,具体如下:

在前面一篇《Python网络编程之TCP套接字简单用法》中,我们实现了tcp客户端与服务器的通信,但是功能十分局限,发送消息与接收消息不能同时进行。

接下来我将通过select这个模块,来实现全双工通信(随时可以接收信息以及发送信息),当然,用多线程也可以完成,这是后话。

那么,select为何物?

select  -在单线程网络服务中器程序中,管理多个套接字连接

select的原型为(rlist,wlist,xlist[,timeout]),其中rlist是等待读取的对象,wlist是等待写入的对象,xlist是等待异常的对象,最后一个是可选对象,指定等待的时间,单位是s.

select()方法的返回值是准备好的对象的三元组,若在timeout的时间内,没有对象准备好,那么返回值将是空的列表。

它采用的是轮询的方式来实现异步通信的。

在下面程序中,目前主要支持1对1通信,当双方任何一方发送字符串‘88'时,表示结束通信。

下面我们来看看具体实现:

首先是服务器。

#!/usr/bin/python
'test TCP server'
from socket import *
from time import ctime
import select
import sys
HOST = ''
PORT = 21567
BUFSIZ = 1024
ADDR = (HOST, PORT)
tcpSerSock = socket(AF_INET, SOCK_STREAM)
tcpSerSock.bind(ADDR)
tcpSerSock.listen(5)
input = [tcpSerSock, sys.stdin]   #input是一个列表,初始有欢迎套接字以及标准输入
while True:
  print 'waiting for connection...'
  tcpCliSock, addr = tcpSerSock.accept()
  print '...connected from:',addr
  input.append(tcpCliSock)  #将服务套接字加入到input列表中
  while True:
    readyInput,readyOutput,readyException = select.select(input,[],[]) #从input中选择,轮流处理client的请求连接(tcpSerSock),client发送来的消息(tcpCliSock),及服务器端的发送消息(stdin)
    for indata in readyInput:
      if indata==tcpCliSock:  #处理client发送来的消息
        data = tcpCliSock.recv(BUFSIZ)
        print data
        if data=='88':
          input.remove(tcpCliSock)
          break
      else:       #处理服务器端的发送消息
        data = raw_input('>')
        if data=='88':
          tcpCliSock.send('%s' %(data))
          input.remove(tcpCliSock)
          break
        tcpCliSock.send('[%s] %s' %(ctime(), data))
    if data=='88':
      break
  tcpCliSock.close()
tcpSerSock.close()

以下是客户端的代码,非常类似,只是与服务器相比不需要处理请求信息而已。

#!/usr/bin/python
'test tcp client'
from socket import *
from time import ctime
import select
import sys
HOST = 'localhost'
PORT = 21567
BUFSIZ = 1024
ADDR = (HOST, PORT)
tcpCliSock = socket(AF_INET, SOCK_STREAM)
tcpCliSock.connect(ADDR)
input = [tcpCliSock,sys.stdin]
while True:
  readyInput,readyOutput,readyException = select.select(input,[],[])
  for indata in readyInput:
    if indata==tcpCliSock:
      data = tcpCliSock.recv(BUFSIZ)
      print data
      if data=='88':
        break
    else:
      data = raw_input('>')
      if data=='88':
        tcpCliSock.send('%s' %(data))
        break
      tcpCliSock.send('[%s] %s' %(ctime(), data))
  if data=='88':
    break
tcpCliSock.close()

目前为止,已经实现了一对一全双工聊天通信啦。

下面当然要思考下,如何实现多对多通信呢?

我们知道,一个服务器可以为多个客户端服务,即,服务器与客户端本身有着一对多的关系,那么,我们是否可以利用服务器作为中间人,用来传达信息,从而实现多对多通信呢?

举个例子,A想要和B通信,则A将信息发送给服务器,然后再通过服务器转发给B。按照这个思路去写,完成多对多通信应该是可以的,有兴趣的可以尝试一下。

更多关于Python相关内容可查看本站专题:《Python Socket编程技巧总结》、《Python数据结构与算法教程》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python入门与进阶经典教程》及《Python文件与目录操作技巧汇总》

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
python中使用百度音乐搜索的api下载指定歌曲的lrc歌词
Jul 18 Python
python Socket之客户端和服务端握手详解
Sep 18 Python
浅谈Python2获取中文文件名的编码问题
Jan 09 Python
http请求 request失败自动重新尝试代码示例
Jan 25 Python
pandas groupby 分组取每组的前几行记录方法
Apr 20 Python
Python之pandas读写文件乱码的解决方法
Apr 20 Python
Python数据类型之列表和元组的方法实例详解
Jul 08 Python
在Django admin中编辑ManyToManyField的实现方法
Aug 09 Python
Python分析微信好友性别比例和省份城市分布比例的方法示例【基于itchat模块】
May 29 Python
基于Python实现视频的人脸融合功能
Jun 12 Python
Matplotlib 折线图plot()所有用法详解
Jul 28 Python
Pycharm自动添加文件头注释和函数注释参数的方法
Oct 23 Python
Python网络编程之TCP套接字简单用法示例
Apr 09 #Python
python3 读写文件换行符的方法
Apr 09 #Python
Python基于TCP实现会聊天的小机器人功能示例
Apr 09 #Python
Python生成任意范围任意精度的随机数方法
Apr 09 #Python
python网络爬虫学习笔记(1)
Apr 09 #Python
Python中defaultdict与lambda表达式用法实例小结
Apr 09 #Python
Python3 实现随机生成一组不重复数并按行写入文件
Apr 09 #Python
You might like
PHP无限分类代码,支持数组格式化、直接输出菜单两种方式
2011/05/18 PHP
PHP实现的汉字拼音转换和公历农历转换类及使用示例
2014/07/01 PHP
PHP5.5新特性之yield理解与用法实例分析
2019/01/11 PHP
jqPlot jquery的页面图表绘制工具
2009/07/25 Javascript
js修改table中Td的值(定义td的双击事件)
2013/01/10 Javascript
JS+CSS实现DIV层的展开、收缩效果
2016/01/28 Javascript
理解javascript中的with关键字
2016/02/15 Javascript
Bootstrap表单布局
2016/07/19 Javascript
jquery 判断selection range 是否在容器中的简单实例
2016/08/02 Javascript
JavaScript数据结构之广义表的定义与表示方法详解
2017/04/12 Javascript
vue better-scroll插件使用详解
2018/01/25 Javascript
vee-validate vue 2.0自定义表单验证的实例
2018/08/28 Javascript
vue使用自定义指令实现拖拽
2021/01/29 Javascript
layui的layedit富文本赋值方法
2019/09/18 Javascript
解决vue-cli项目开发运行时内存暴涨卡死电脑问题
2019/10/29 Javascript
TypeScript高级用法的知识点汇总
2019/12/17 Javascript
Element Cascader 级联选择器的使用示例
2020/07/27 Javascript
python网络编程学习笔记(七):HTML和XHTML解析(HTMLParser、BeautifulSoup)
2014/06/09 Python
Windows下用py2exe将Python程序打包成exe程序的教程
2015/04/08 Python
解决Python中字符串和数字拼接报错的方法
2016/10/23 Python
python+matplotlib实现礼盒柱状图实例代码
2018/01/16 Python
Python+selenium 获取一组元素属性值的实例
2018/06/22 Python
Django框架自定义模型管理器与元选项用法分析
2019/07/22 Python
pytorch 修改预训练model实例
2020/01/18 Python
Python2和Python3中@abstractmethod使用方法
2020/02/04 Python
详解canvas绘制网络字体几种方法
2019/08/27 HTML / CSS
入党自我鉴定范文
2013/10/04 职场文书
信息技术专业大学生个人的自我评价
2013/10/05 职场文书
2014年党员整改措施范文
2014/09/21 职场文书
2015年保险公司内勤工作总结
2015/05/23 职场文书
初中生入团申请书范文(五篇)
2019/10/16 职场文书
一文搞懂如何实现Go 超时控制
2021/03/30 Python
Vue和Flask通信的实现
2021/05/19 Vue.js
JVM钩子函数的使用场景详解
2021/08/23 Java/Android
Winsows11性能如何? win11性能测评多核竟比Win10差了10%
2021/11/21 数码科技
Zabbix6通过ODBC方式监控Oracle 19C的详细过程
2022/09/23 Servers