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 相关文章推荐
pygame学习笔记(5):游戏精灵
Apr 15 Python
详解Python的Django框架中的模版相关知识
Jul 15 Python
好用的Python编辑器WingIDE的使用经验总结
Aug 31 Python
Python的时间模块datetime详解
Apr 17 Python
基于python 字符编码的理解
Sep 02 Python
详解Python中 sys.argv[]的用法简明解释
Dec 20 Python
Django的HttpRequest和HttpResponse对象详解
Jan 26 Python
Python实现的爬取网易动态评论操作示例
Jun 06 Python
wxPython绘图模块wxPyPlot实现数据可视化
Nov 19 Python
python实现拼接图片
Mar 23 Python
Django实现随机图形验证码的示例
Oct 15 Python
详解python中的三种命令行模块(sys.argv,argparse,click)
Dec 15 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+swoole对client数据实时更新(一)
2016/01/07 PHP
TP5(thinkPHP5)框架基于ajax与后台数据交互操作简单示例
2018/09/03 PHP
yii2 在控制器中验证请求参数的使用方法
2019/06/19 PHP
JQuery 简便实现页面元素数据验证功能
2007/03/24 Javascript
javascript下判断一个对象是否具有指定名称的属性的的代码
2010/01/11 Javascript
jquery的Tooltip插件 qtip使用详细说明
2010/09/08 Javascript
jQuery时间插件jquery.clock.js用法实例(5个示例)
2016/01/14 Javascript
Bootstrap整体框架之JavaScript插件架构
2016/12/15 Javascript
React-Native做一个文本输入框组件的实现代码
2017/08/10 Javascript
你可能不知道的JSON.stringify()详解
2017/08/17 Javascript
jQuery中.attr()和.data()的区别分析
2017/09/03 jQuery
微信小程序开发之IOS和Android兼容的问题
2017/09/26 Javascript
简化vuex的状态管理方案的方法
2018/06/02 Javascript
微信小程序scroll-x失效的完美解决方法
2018/07/18 Javascript
node使用Mongoose类库实现简单的增删改查
2018/11/08 Javascript
深入理解vue中的slot与slot-scope
2019/04/22 Javascript
javascript中的闭包概念与用法实践分析
2019/07/26 Javascript
用Python编写web API的教程
2015/04/30 Python
Python实现字典去除重复的方法示例
2017/07/31 Python
python去除拼音声调字母,替换为字母的方法
2018/11/28 Python
Python 微信之获取好友昵称并制作wordcloud的实例
2019/02/21 Python
python使用Plotly绘图工具绘制散点图、线形图
2019/04/02 Python
Python求两点之间的直线距离(2种实现方法)
2019/07/07 Python
8段用于数据清洗Python代码(小结)
2019/10/31 Python
解决Jupyter NoteBook输出的图表太小看不清问题
2020/04/16 Python
H5调用相机拍照并压缩图片的实例代码
2017/07/20 HTML / CSS
Ajax主要包含了哪些技术
2014/06/12 面试题
英文版银行求职信
2013/10/09 职场文书
酒店人事专员岗位职责
2013/12/19 职场文书
最热门的自我评价
2013/12/30 职场文书
个人简历自我评价
2014/01/06 职场文书
酒店总经理助理岗位职责
2014/02/01 职场文书
党员公开承诺书范文
2014/03/25 职场文书
2015年党风建设工作总结
2015/04/29 职场文书
创业计划书之美容店
2019/09/16 职场文书
详解Spring Security如何在权限中使用通配符
2022/06/28 Java/Android