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获得两个数组交集、并集、差集的方法
Mar 27 Python
python使用urllib2实现发送带cookie的请求
Apr 28 Python
python中pandas.DataFrame的简单操作方法(创建、索引、增添与删除)
Mar 12 Python
Python实现压缩和解压缩ZIP文件的方法分析
Sep 28 Python
使用tensorflow实现线性svm
Sep 07 Python
基于wxPython的GUI实现输入对话框(1)
Feb 27 Python
PyQt5实现简易电子词典
Jun 25 Python
在python image 中安装中文字体的实现方法
Aug 22 Python
PyQt5的相对布局管理的实现
Aug 07 Python
Python实现树莓派摄像头持续录像并传送到主机的步骤
Nov 30 Python
Python实现石头剪刀布游戏
Jan 20 Python
python基础入门之普通操作与函数(三)
Jun 13 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设计模式之迭代器模式的深入解析
2013/06/13 PHP
你可能不知道PHP get_meta_tags()函数
2014/05/12 PHP
php实现删除空目录的方法
2015/03/16 PHP
PHP扩展迁移为PHP7扩展兼容性问题记录
2016/02/15 PHP
PHP使用PDO操作数据库的乱码问题解决方法
2016/04/08 PHP
php函数mkdir实现递归创建层级目录
2016/10/27 PHP
浏览器加载、渲染和解析过程黑箱简析
2012/11/29 Javascript
js网页版计算器的简单实现
2013/07/02 Javascript
node.js 开发指南 ? Node.js 连接 MySQL 并进行数据库操作
2014/07/29 Javascript
JavaScript让Textarea支持tab按键的方法
2015/06/26 Javascript
javascript比较两个日期相差天数的方法
2015/07/24 Javascript
Jquery和JS获取ul中li标签的实现方法
2016/06/02 Javascript
JS基于递归实现倒计时效果的方法
2016/11/26 Javascript
Boostrap栅格系统与自己额外定义的媒体查询的冲突问题
2017/02/19 Javascript
Ajax异步获取html数据中包含js方法无效的解决方法
2017/02/20 Javascript
jQuery图片切换动画效果
2017/02/28 Javascript
web.js.字符串与正则表达式操作
2017/05/13 Javascript
angularjs实现猜大小功能
2017/10/23 Javascript
详解webpack4之splitchunksPlugin代码包分拆
2018/12/04 Javascript
layui table复选框禁止某几条勾选的实例
2019/09/20 Javascript
JS 事件机制完整示例分析
2020/01/15 Javascript
python实现排序算法
2014/02/14 Python
python之wxPython菜单使用详解
2014/09/28 Python
Python实现批量检测HTTP服务的状态
2016/10/27 Python
python爬取微信公众号文章
2018/08/31 Python
django主动抛出403异常的方法详解
2019/01/04 Python
python如何实现从视频中提取每秒图片
2020/10/22 Python
python__name__原理及用法详解
2019/11/02 Python
医科大学生的自我评价
2013/12/04 职场文书
社区党总支书记先进事迹材料
2014/01/24 职场文书
勤俭节约倡议书
2014/04/14 职场文书
项目委托协议书(最新)
2014/09/13 职场文书
幼儿园大班教师随笔
2015/08/14 职场文书
Python如何配置环境变量详解
2021/05/18 Python
新手必备之MySQL msi版本下载安装图文详细教程
2021/05/21 MySQL
Java 在线考试云平台的实现
2021/11/23 Java/Android