在Python中使用异步Socket编程性能测试


Posted in Python onJune 25, 2014

OK,首先写一个python socket的server段,对开放三个端口:10000,10001,10002.krondo的例子中是每个server绑定一个端口,测试的时候需要分别开3个shell,分别运行.这太麻烦了,就分别用三个Thread来运行这些services.

import optparse 
import os 
import socket 
import time 
from threading import Thread 
import StringIO 
  
txt = '''1111 
2222 
3333 
4444 
''' 
  
  def server(listen_socket): 
  while True: 
    buf = StringIO.StringIO(txt) 
    sock, addr = listen_socket.accept() 
    print 'Somebody at %s wants poetry!' % (addr,) 
    while True: 
        try: 
          line = buf.readline().strip() 
          if not line: 
            sock.close() 
            break 
          sock.sendall(line) # this is a blocking call 
          print 'send bytes to client:%s' % line 
          #sock.close() 
        except socket.error: 
          sock.close() 
          break 
        time.sleep(1) #server和client连接后,server会故意每发送一个单词后等待一秒钟后再发送另一个单词 
  
  def main(): 
  ports = [10000, 10001, 10002] 
  for port in ports: 
    listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 
    addres = (str('127.0.0.1'), port) 
    listen_socket.bind(addres) 
    listen_socket.listen(5) 
    print "start listen at:%s" % (port,) 
    worker = Thread(target = server, args = [listen_socket]) 
    worker.setDaemon(True) 
    worker.start() 
  
  if __name__ == '__main__': 
  main() 
  while True: 
    time.sleep(0.1) #如果不sleep的话,CPU会被Python完全占用了 
    pass

下面是一个client,没有才用异步网络,连接这个三个端口的server:

import socket 
  
  
if __name__ == '__main__': 
  ports = [10000, 10001, 10002] 
  for port in ports: 
    address = (str('127.0.0.1'), port) 
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
    sock.connect(address) 
    poem = '' 
    while True: 
      data = sock.recv(4) 
      if not data: 
        sock.close() 
        break 
      poem += data 
    print poem

下面用异步的client来读取,代码如下:

import datetime, errno, optparse, select, socket 
  
def connect(port): 
  """Connect to the given server and return a non-blocking socket.""" 
  address = (str('127.0.0.1'), port) 
  sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
  sock.connect(address) 
  sock.setblocking(0) 
  return sock 
  
def format_address(address): 
  host, port = address 
  return '%s:%s' % (host or '127.0.0.1', port) 
  
if __name__ == '__main__': 
  ports = [10000, 10001, 10002] 
  start = datetime.datetime.now() 
  
  sockets = map(connect, ports) 
  poems = dict.fromkeys(sockets, '') # socket -> accumulated poem  
  
  # socket -> task numbers 
  sock2task = dict([(s, i + 1) for i, s in enumerate(sockets)]) 
  sockets = list(sockets) # make a copy 
  
  while sockets: 
    #运用select来确保那些可读取的异步socket可以立即开始读取IO 
    #OS不停的搜索目前可以read的socket,有的话就返回rlist 
    rlist, _, _ = select.select(sockets, [], []) 
    for sock in rlist: 
      data = '' 
      while True: 
        try: 
          new_data = sock.recv(1024) 
        except socket.error, e: 
          if e.args[0] == errno.EWOULDBLOCK: 
            break 
          raise 
        else: 
          if not new_data: 
            break 
          else: 
            print new_data 
            data += new_data 
  
      task_num = sock2task[sock] 
      if not data: 
        sockets.remove(sock) 
        sock.close() 
        print 'Task %d finished' % task_num 
      else: 
        addr_fmt = format_address(sock.getpeername()) 
        msg = 'Task %d: got %d bytes of poetry from %s' 
        print msg % (task_num, len(data), addr_fmt) 
  
      poems[sock] += data 
  
  elapsed = datetime.datetime.now() - start 
  print 'Got poems in %s' % elapsed

结果只需要4秒就完成了读取任务。效率是刚才同步socket的三倍。对客户端的异步改造主要有两点:

同步模式下,客户端分别创建socket;而在异步模式下,client开始就创建了所有的socket。
通过“sock.setblocking(0)”设置socket为异步模式。
通过Unix系统的select俩返回可读取IO
最为核心的是26行和29行。尤其是29行的select操作返回待读取socket的列表。

Python 相关文章推荐
用Python解决计数原理问题的方法
Aug 04 Python
用tensorflow搭建CNN的方法
Mar 05 Python
解决seaborn在pycharm中绘图不出图的问题
May 24 Python
python3实现SMTP发送邮件详细教程
Jun 19 Python
Python3 执行系统命令并获取实时回显功能
Jul 09 Python
python socket通信编程实现文件上传代码实例
Dec 14 Python
python使用梯度下降和牛顿法寻找Rosenbrock函数最小值实例
Apr 02 Python
Python描述数据结构学习之哈夫曼树篇
Sep 07 Python
Python用dilb提取照片上人脸的示例
Oct 26 Python
Python GUI库Tkiner使用方法代码示例
Nov 27 Python
python利用proxybroker构建爬虫免费IP代理池的实现
Feb 21 Python
详细介绍python操作RabbitMq
Apr 12 Python
Python开发的单词频率统计工具wordsworth使用方法
Jun 25 #Python
python 字典(dict)遍历的四种方法性能测试报告
Jun 25 #Python
用python登录Dr.com思路以及代码分享
Jun 25 #Python
python正则表达式re模块详解
Jun 25 #Python
Python通过websocket与js客户端通信示例分析
Jun 25 #Python
Flask框架学习笔记(一)安装篇(windows安装与centos安装)
Jun 25 #Python
Python中文编码那些事
Jun 25 #Python
You might like
基于PHP开发中的安全防范知识详解
2013/06/06 PHP
php判断字符串在另一个字符串位置的方法
2014/02/27 PHP
基于yaf框架和uploadify插件,做的一个导入excel文件,查看并保存数据的功能
2017/01/24 PHP
jquery的键盘事件修改代码
2011/02/24 Javascript
javascript 另一种图片滚动切换效果思路
2012/04/20 Javascript
jQuery中get和post方法传值测试及注意事项
2014/08/08 Javascript
javascript解析json实例详解
2014/11/05 Javascript
jquery实现勾选复选框触发事件给input赋值
2015/02/01 Javascript
JS+CSS实现自适应选项卡宽度的圆角滑动门效果
2015/09/15 Javascript
jQuery模拟360浏览器切屏效果幻灯片(附demo源码下载)
2016/01/29 Javascript
jQuery表格插件datatables用法汇总
2016/03/29 Javascript
分享JS数组求和与求最大值的方法
2016/08/11 Javascript
Vue.js快速入门教程
2016/09/07 Javascript
微信小程序开发之圆形菜单 仿建行圆形菜单实例
2016/12/12 Javascript
js中作用域的实例解析
2017/03/16 Javascript
Easyui ueditor 整合解决不能编辑的问题(推荐)
2017/06/25 Javascript
VUE长按事件需求详解
2017/10/18 Javascript
vue实现图片滚动的示例代码(类似走马灯效果)
2018/03/03 Javascript
Vue 组件传值几种常用方法【总结】
2018/05/28 Javascript
vue router 用户登陆功能的实例代码
2019/04/24 Javascript
JavaScript实现表单验证功能
2020/12/09 Javascript
Python算法之栈(stack)的实现
2014/08/18 Python
python脚本爬取字体文件的实现方法
2017/04/29 Python
python分布式环境下的限流器的示例
2017/10/26 Python
浅谈python数据类型及类型转换
2017/12/18 Python
Python输出由1,2,3,4组成的互不相同且无重复的三位数
2018/02/01 Python
python实现自动获取IP并发送到邮箱
2018/12/26 Python
对python中词典的values值的修改或新增KEY详解
2019/01/20 Python
Python django框架应用中实现获取访问者ip地址示例
2019/05/17 Python
tensorflow -gpu安装方法(不用自己装cuda,cdnn)
2020/01/20 Python
Python如何操作docker redis过程解析
2020/08/10 Python
加拿大在线旅游公司:Flighthub
2019/03/11 全球购物
新西兰网上购物,折扣店:BestDeals.co.nz
2019/03/20 全球购物
研究生求职推荐信范文
2013/11/30 职场文书
生日寿宴答谢词
2014/01/19 职场文书
公司委托书格式范文
2014/10/09 职场文书