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 相关文章推荐
Django中对数据查询结果进行排序的方法
Jul 17 Python
Python编程之string相关操作实例详解
Jul 22 Python
利用python批量修改word文件名的方法示例
Oct 17 Python
利用Tkinter和matplotlib两种方式画饼状图的实例
Nov 06 Python
python数字图像处理之高级形态学处理
Apr 27 Python
Scrapy基于selenium结合爬取淘宝的实例讲解
Jun 13 Python
用Python实现筛选文件脚本的方法
Oct 27 Python
解决python flask中config配置管理的问题
Jul 26 Python
Django中提示消息messages的设置方式
Nov 15 Python
python 一维二维插值实例
Apr 22 Python
详解python中[-1]、[:-1]、[::-1]、[n::-1]使用方法
Apr 25 Python
如何利用pygame实现打飞机小游戏
May 30 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 模拟POST|GET操作实现代码
2010/07/20 PHP
php visitFile()遍历指定文件夹函数
2010/08/21 PHP
smarty模板引擎基础知识入门
2015/03/30 PHP
PHP操作mysql数据库分表的方法
2016/06/09 PHP
PHP实现websocket通信的方法示例
2018/08/28 PHP
[Web]防止用户复制页面内容和另存页面的方法
2009/02/06 Javascript
初识javascript 文档碎片
2010/07/13 Javascript
Jquery 选中表格一列并对表格排序实现原理
2012/12/15 Javascript
用Javascript来生成ftp脚本的小例子
2013/07/03 Javascript
Jquery attr("checked") 返回checked或undefined 获取选中失效
2013/10/10 Javascript
封装了jQuery的Ajax请求全局配置
2015/02/05 Javascript
基于JS实现PHP的sprintf函数实例
2015/11/14 Javascript
JQuery实现简单的图片滑动切换特效
2015/11/22 Javascript
深入理解angularjs过滤器
2016/05/25 Javascript
Bootstrap表单Form全面解析
2016/06/13 Javascript
jQuery实现简单的网页换肤效果示例
2016/09/18 Javascript
利用React-router+Webpack快速构建react程序
2016/10/27 Javascript
TypeScript入门-接口
2017/03/30 Javascript
vue项目国际化vue-i18n的安装使用教程
2018/03/14 Javascript
vue 实现axios拦截、页面跳转和token 验证
2018/07/17 Javascript
重学 JS:为啥 await 不能用在 forEach 中详解
2019/04/15 Javascript
vue视频播放暂停代码
2019/11/08 Javascript
Preload基础使用方法详解
2020/02/03 Javascript
nginx部署多个vue项目的方法示例
2020/09/06 Javascript
javascript中导出与导入实现模块化管理教程
2020/12/03 Javascript
Python中出现IndentationError:unindent does not match any outer indentation level错误的解决方法
2020/04/18 Python
Python之列表实现栈的工作功能
2019/01/28 Python
python通过http下载文件的方法详解
2019/07/26 Python
Python 用matplotlib画以时间日期为x轴的图像
2019/08/06 Python
OpenCV中VideoCapture类的使用详解
2020/02/14 Python
美国创意礼品网站:UncommonGoods
2017/02/03 全球购物
电大本科自我鉴定
2014/02/05 职场文书
开工典礼策划方案
2014/05/23 职场文书
2015年安全教育月活动总结
2015/03/26 职场文书
幼儿园安全教育随笔
2015/08/14 职场文书
2016年三八节红领巾广播稿
2015/12/17 职场文书