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使用心得之获得github代码库列表
Jun 25 Python
Python中isnumeric()方法的使用简介
May 19 Python
Python中用于转换字母为小写的lower()方法使用简介
May 19 Python
分析python切片原理和方法
Dec 19 Python
Python使用base64模块进行二进制数据编码详解
Jan 11 Python
Python学习笔记之open()函数打开文件路径报错问题
Apr 28 Python
Python迭代器与生成器用法实例分析
Jul 09 Python
Django的models中on_delete参数详解
Jul 16 Python
基于Python实现拆分和合并GIF动态图
Oct 22 Python
python 检查数据中是否有缺失值,删除缺失值的方式
Dec 02 Python
Python 实现try重新执行
Dec 21 Python
Python的3种运行方式:命令行窗口、Python解释器、IDLE的实现
Oct 10 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聊天室技术
2006/10/09 PHP
PHP 飞信好友免费短信API接口开源版
2010/07/22 PHP
PHP实现的封装验证码类详解
2013/06/18 PHP
实现PHP多线程异步请求的3种方法
2014/01/17 PHP
php中in_array函数用法分析
2014/11/15 PHP
php基于curl实现的股票信息查询类实例
2016/11/11 PHP
PHP用PDO如何封装简单易用的DB类详解
2017/07/30 PHP
Yii redis集合的基本使用教程
2020/06/14 PHP
jquery监控数据是否变化(修正版)
2011/04/12 Javascript
js中字符替换函数String.replace()使用技巧
2011/08/14 Javascript
Javascript字符串对象的常用方法简明版
2014/06/26 Javascript
JQuery实现当鼠标停留在某区域3秒后自动执行
2014/09/09 Javascript
jQuery实现简单的间隔向上滚动效果
2015/03/09 Javascript
详解JavaScript中setSeconds()方法的使用
2015/06/11 Javascript
JavaScript DOM 对象深入了解
2016/07/20 Javascript
类似于QQ的右滑删除效果的实现方法
2016/10/16 Javascript
JS实现重新加载当前页面
2016/11/29 Javascript
使用nodejs爬取前程无忧前端技能排行
2017/05/06 NodeJs
[15:58]DOTA2国际邀请赛采访专栏:Tongfu.Sansheng&KingJ,DK.rOtk
2013/08/08 DOTA
[01:27]2014DOTA2展望TI 剑指西雅图IG战队专访
2014/06/30 DOTA
Python工程师面试题 与Python基础语法相关
2016/01/14 Python
解决python3 pika之连接断开的问题
2018/12/18 Python
Python+OpenCV图片局部区域像素值处理详解
2019/01/23 Python
Python3利用Dlib实现摄像头实时人脸检测和平铺显示示例
2019/02/21 Python
python ddt数据驱动最简实例代码
2019/02/22 Python
Python3.5 + sklearn利用SVM自动识别字母验证码方法示例
2019/05/10 Python
如何通过50行Python代码获取公众号全部文章
2019/07/12 Python
PyPDF2读取PDF文件内容保存到本地TXT实例
2020/05/12 Python
巴西化妆品商店:Lojas Rede
2019/07/26 全球购物
临床护士自荐信
2014/01/31 职场文书
军训自我鉴定范文
2014/02/13 职场文书
入党介绍人评语
2014/05/06 职场文书
庆祝国庆节标语
2014/10/09 职场文书
后天观后感
2015/06/08 职场文书
私人贷款担保书该怎么写呢?
2019/07/02 职场文书
Python利器openpyxl之操作excel表格
2021/04/17 Python