在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 相关文章推荐
PHP网页抓取之抓取百度贴吧邮箱数据代码分享
Apr 13 Python
Python使用functools模块中的partial函数生成偏函数
Jul 02 Python
Python使用迭代器打印螺旋矩阵的思路及代码示例
Jul 02 Python
python中的格式化输出用法总结
Jul 28 Python
Python面向对象基础入门之编码细节与注意事项
Dec 11 Python
python的内存管理和垃圾回收机制详解
May 18 Python
python模拟键盘输入 切换键盘布局过程解析
Aug 15 Python
Python求正态分布曲线下面积实例
Nov 20 Python
PIL包中Image模块的convert()函数的具体使用
Feb 26 Python
tensorflow 动态获取 BatchSzie 的大小实例
Jun 30 Python
pycharm 使用anaconda为默认环境的操作
Feb 05 Python
python爬虫之selenium库的安装及使用教程
May 23 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
linux下为php添加curl扩展的方法
2011/07/29 PHP
php实现session自定义会话处理器的方法
2015/01/27 PHP
Zend Framework过滤器Zend_Filter用法详解
2016/12/09 PHP
PHP 实现base64编码文件上传出现问题详解
2020/09/01 PHP
js类中的公有变量和私有变量
2008/07/24 Javascript
javascript对象之内置对象Math使用方法
2010/04/16 Javascript
基于jquery ajax 用户无刷新登录方法详解
2012/04/28 Javascript
Array 重排序方法和操作方法的简单实例
2014/01/24 Javascript
输入框过滤非数字的js代码
2014/09/18 Javascript
Javascript基础知识(二)事件
2014/09/29 Javascript
node.js中的fs.close方法使用说明
2014/12/17 Javascript
sails框架的学习指南
2014/12/22 Javascript
JS定时器使用,定时定点,固定时刻,循环执行详解
2016/05/31 Javascript
jQuery实现指定区域外单击关闭指定层的方法【经典】
2016/06/22 Javascript
jquery checkbox无法用attr()二次勾选问题的解决方法
2016/07/22 Javascript
javascript判断元素存在和判断元素存在于实时的dom中的方法
2017/01/17 Javascript
Angular.JS中的指令引用template与指令当做属性详解
2017/03/30 Javascript
JS实现线性表的顺序表示方法示例【经典数据结构】
2017/04/11 Javascript
JS 实现获取验证码 倒计时功能
2018/10/29 Javascript
jquery无缝图片轮播组件封装
2020/11/25 jQuery
微信小程序实现录音时的麦克风动画效果实例
2019/05/18 Javascript
vite2.0+vue3移动端项目实战详解
2021/03/03 Vue.js
浅谈Python的Django框架中的缓存控制
2015/07/24 Python
python和shell监控linux服务器的详细代码
2018/06/22 Python
Python使用random.shuffle()打乱列表顺序的方法
2018/11/08 Python
opencv调整图像亮度对比度的示例代码
2019/09/27 Python
10个python3常用排序算法详细说明与实例(快速排序,冒泡排序,桶排序,基数排序,堆排序,希尔排序,归并排序,计数排序)
2020/03/17 Python
达拉斯牛仔官方商店:Dallas Cowboys Pro Shop
2018/02/10 全球购物
蔻驰法国官网:COACH法国
2018/11/14 全球购物
创意广告词
2014/03/17 职场文书
教师先进工作者事迹材料
2014/05/01 职场文书
我的中国梦演讲稿高中篇
2014/08/19 职场文书
群众路线教育实践活动对照检查材料思想汇报(副处级领导)
2014/10/04 职场文书
党员批评与自我批评发言稿
2014/10/14 职场文书
2015年学校医务室工作总结
2015/07/20 职场文书
游戏开发中如何使用CocosCreator进行音效处理
2021/04/14 Javascript