在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发送伪造的arp请求
Jan 09 Python
Python的Twisted框架中使用Deferred对象来管理回调函数
May 25 Python
使用PyInstaller将Python程序文件转换为可执行程序文件
Jul 08 Python
Python实现网络端口转发和重定向的方法
Sep 19 Python
详解Python pygame安装过程笔记
Jun 05 Python
神经网络python源码分享
Dec 15 Python
python操作excel文件并输出txt文件的实例
Jul 10 Python
python 实现求解字符串集的最长公共前缀方法
Jul 20 Python
Python数据类型之Tuple元组实例详解
May 08 Python
pandas实现DataFrame显示最大行列,不省略显示实例
Dec 26 Python
Python3 实现爬取网站下所有URL方式
Jan 16 Python
TensorFlow tf.nn.softmax_cross_entropy_with_logits的用法
Apr 19 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
Win2003服务器安全加固设置--进一步提高服务器安全性
2007/05/23 PHP
用php实现的下载css文件中的图片的代码
2010/02/08 PHP
用mysql_fetch_array()获取当前行数据的方法详解
2013/06/05 PHP
ThinkPHP实现跨模块调用操作方法概述
2014/06/20 PHP
PHP判断JSON对象是否存在的方法(推荐)
2016/07/06 PHP
laravel 错误处理,接口错误返回json代码
2019/10/25 PHP
JavaScritp添加url参数并将参数加入到url中及更改url参数的方法
2015/10/26 Javascript
jQuery实现弹幕效果
2017/02/17 Javascript
JavaScript学习总结之正则的元字符和一些简单的应用
2017/06/30 Javascript
jquery ajax加载数据前台渲染方式 不用for遍历的方法
2018/08/09 jQuery
vue 2.8.2版本配置刚进入时候的默认页面方法
2018/09/21 Javascript
原生JS实现旋转轮播图+文字内容切换效果【附源码】
2018/09/29 Javascript
详解基于 Node.js 的轻量级云函数功能实现
2019/07/08 Javascript
解决VUE 在IE下出现ReferenceError: Promise未定义的问题
2020/11/07 Javascript
[07:49]2014DOTA2国际邀请赛 Newbee夺冠后采访xiao8坦言奖金会上交
2014/07/23 DOTA
Python爬取京东的商品分类与链接
2016/08/26 Python
安装Python的教程-Windows
2017/07/22 Python
pandas string转dataframe的方法
2018/04/11 Python
python脚本生成caffe train_list.txt的方法
2018/04/27 Python
python3处理含有中文的url方法
2018/05/10 Python
解决Ubuntu pip 安装 mysql-python包出错的问题
2018/06/11 Python
python多线程并发实例及其优化
2019/06/27 Python
如何将你的应用迁移到Python3的三个步骤
2019/12/22 Python
用Python在Excel里画出蒙娜丽莎的方法示例
2020/04/28 Python
python使用dlib进行人脸检测和关键点的示例
2020/12/05 Python
Html5新增标签有哪些
2017/04/13 HTML / CSS
澳大利亚自然和有机的健康美容产品一站式商店:Ziani Beauty
2017/12/28 全球购物
Skyscanner加拿大:全球旅行搜索平台
2018/11/19 全球购物
火山动力Java笔试题
2014/06/26 面试题
高级方案规划工程师岗位职责
2013/11/29 职场文书
小学生竞选班干部演讲稿
2014/04/24 职场文书
大学优秀班主任事迹材料
2014/05/02 职场文书
保护地球的标语
2014/06/17 职场文书
机关作风整顿个人整改措施2014
2014/09/17 职场文书
大学生毕业评语
2014/12/31 职场文书
简单谈谈Python面向对象的相关知识
2021/06/28 Python