ping的源码
http://techpool.iteye.com/blog/661864
非阻塞式的socket stacklesssocket.py下载
http://code.google.com/p/stacklessexamples/wiki/StacklessNetworking
参考了张沈鹏的抓网页演示。
说明:
python的原生socket实现是阻塞式的,所以即使用协程并发,也是串行执行的。
#!/usr/bin/env python
#coding=gbk
"""
mping.py
"""
import stackless
import sys
import ping
ICMP_DATA_STR = 56
#创建通道
ch = []
i=0
while i<5:
ch.append(stackless.channel())
i=i+1
chr=stackless.channel()
#创建函数
def pingip(i):
while 1:
msg=ch[i].receive()
print "%s recv %s" % (i,msg)
ip="192.168.25.%d" % i
print ip
ping.pingNode(alive=0, timeout=1.0, ipv6=0, number=1, \
node=ip, flood=0, size=ICMP_DATA_STR)
chr.send(i)
def report():
while 1:
msg=chr.receive()
print "report recv %s" % msg
def start():
j=1
while j<5:
ch[j].send(j)
j=j+1
#创建协程
j=0
while j<5:
stackless.tasklet(pingip)(j)
j=j+1
stackless.tasklet(report)()
stackless.tasklet(start)()
#开始运行
stackless.run()
#start()
通过stackelsssock改造,可以实现异步networkio
#!/usr/bin/env python
#coding=gbk
"""
mping.py
"""
import stackless
import stacklesssocket
import sys
import ping
ICMP_DATA_STR = 56
stacklesssocket.install()
#创建通道
ch = []
i=0
while i<5:
ch.append(stackless.channel())
i=i+1
chr=stackless.channel()
#创建函数
def pingip(i):
while 1:
msg=ch[i].receive()
print "%s recv %s" % (i,msg)
ip="192.168.25.%d" % msg
print ip
ping.pingNode(alive=0, timeout=1.0, ipv6=0, number=1, \
node="192.168.25.1", flood=0, size=ICMP_DATA_STR)
chr.send(i)
def report():
while 1:
msg=chr.receive()
print "report recv %s" % msg
def start():
j=1
while j<5:
ch[j].send(j)
j=j+1
#创建协程
j=0
while j<5:
stackless.tasklet(pingip)(j)
j=j+1
stackless.tasklet(report)()
stackless.tasklet(start)() #这样才会等待所有协程结束
#开始运行
stackless.run()
#start() #不会等待协程执行完
二者差别很小。 从输出可以看到ping的测试和结果是异步的
异步方式明显要快很多
但是大并发环境下的具体性能和稳定性如何,还需要测试。
以前c做的多线程程序在大量并发环境下会有丢包的情况.和系统的socket机制和参数应该也有关系。
后记:
经过测试,存在不小问题
在目标地址存在不通的情况下(用ping命令或者单进程测试都确实不通)
用协程跑出来结果居然是通的
说明stacklesssocket在处理异常的情况下还是有问题
另外,协程的数量也有限制,否则会挂死
这些目前看是stacklesssocket的问题,但是缺了这个,stackless本身也就没有多大价值了
也许通过修改stacklesssocket的底层代码,可以解决吧