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检测lvs real server状态
Jan 22 Python
使用Python对IP进行转换的一些操作技巧小结
Nov 09 Python
python 字典中文key处理,读取,比较方法
Jul 06 Python
Python使用matplotlib绘制三维图形示例
Aug 25 Python
浅谈Python脚本开头及导包注释自动添加方法
Oct 27 Python
对Python3 解析html的几种操作方式小结
Feb 16 Python
python实现向微信用户发送每日一句 python实现微信聊天机器人
Mar 27 Python
python里 super类的工作原理详解
Jun 19 Python
Python中字符串List按照长度排序
Jul 01 Python
Python turtle画图库&&画姓名实例
Jan 19 Python
Python中使用filter过滤列表的一个小技巧分享
May 02 Python
使用Python将xmind脑图转成excel用例的实现代码(一)
Oct 12 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
通过html表格发电子邮件
2006/10/09 PHP
php动态实现表格跨行跨列实现代码
2012/11/06 PHP
php实现图片转换成ASCII码的方法
2015/04/03 PHP
php实现模拟post请求用法实例
2015/07/11 PHP
Symfony2学习笔记之控制器用法详解
2016/03/17 PHP
php版微信公众号接口实现发红包的方法
2016/10/14 PHP
通过PHP实现用户注册后邮箱验证激活
2020/11/10 PHP
调用js时ie6和ie7,ff的区别
2009/08/19 Javascript
分享一则javascript 调试技巧
2015/01/02 Javascript
Javascript必知必会(四)js类型转换
2016/06/08 Javascript
JS产生随机数的几个用法详解
2016/06/22 Javascript
Bootstrap导航条可点击和鼠标悬停显示下拉菜单的实现代码
2016/06/23 Javascript
微信小程序-消息提示框实例
2016/11/24 Javascript
JavaScript和jQuery制作光棒效果
2017/02/24 Javascript
nodejs动态创建二维码的方法
2017/08/12 NodeJs
vuex与组件联合使用的方法
2018/05/10 Javascript
基于jQuery实现的设置文本区域的光标位置
2018/06/15 jQuery
vue实现文字横向无缝走马灯组件效果的实例代码
2019/04/09 Javascript
Angular5整合富文本编辑器TinyMCE的方法(汉化+上传)
2020/05/26 Javascript
[01:24:34]2014 DOTA2华西杯精英邀请赛5 24 DK VS LGD
2014/05/25 DOTA
[01:24:16]2018DOTA2亚洲邀请赛 4.6 全明星赛
2018/04/10 DOTA
[57:47]Fnatic vs Winstrike 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
python复制文件代码实现
2013/12/23 Python
python通过pil模块将raw图片转换成png图片的方法
2015/03/16 Python
详解Python中的各种函数的使用
2015/05/24 Python
详解Python中的相对导入和绝对导入
2017/01/06 Python
利用Anaconda完美解决Python 2与python 3的共存问题
2017/05/25 Python
python实现稀疏矩阵示例代码
2017/06/09 Python
Django Admin 实现外键过滤的方法
2017/09/29 Python
ubuntu17.4下为python和python3装上pip的方法
2018/06/12 Python
对python中for、if、while的区别与比较方法
2018/06/25 Python
解决win64 Python下安装PIL出错问题(图解)
2018/09/03 Python
探秘TensorFlow 和 NumPy 的 Broadcasting 机制
2020/03/13 Python
荷兰手表网站:Watch2Day
2018/07/02 全球购物
退学证明范本3篇
2014/10/29 职场文书
幼儿园中班教师个人工作总结
2015/02/06 职场文书