本文实例讲述了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程序设计有所帮助。
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。