viv*_*vek 2 python twisted callback
目标:尝试与服务器列表建立TCP连接,并在连接成功并提示输入密码时进行打印
问题:似乎to_check -= 1我的回调(名为connected)和errback(名为failed)中的statement()永远不会被执行,即使这些函数中的print语句是.
from twisted.internet import protocol, defer
import sys
class myProto(protocol.Protocol):
got = ''
def dataReceived(self,data):
#print data
self.got += data
if "Password:" in data:
self.transport.loseConnection()
def connectionLost(self,reason):
#print self.got
if "Password:" in self.got:
self.factory.success("and was prompted for password")
else:
self.factory.success("But was not prompted for password")
class myFactory(protocol.ClientFactory):
protocol = myProto
def __init__(self,deferred,host):
self.deferred = deferred
self.host = host
print "Trying Connection to %s ..." % host
def success(self,askpass):
if self.deferred is not None:
d, self.deferred = self.deferred , None
d.callback([self.host,askpass])
def clientConnectionFailed(self, connector, reason):
if self.deferred is not None:
d, self.deferred = self.deferred, None
d.errback(reason)
def check_conn(host, port):
from twisted.internet import reactor
d = defer.Deferred()
factory = myFactory(d,host)
reactor.connectTCP(host,port,factory)
return d
def main():
ip = "10.1.1."
port = 23
total = 10
to_check = total
from twisted.internet import reactor
def connected(whathappened):
print >>sys.stdout, "Successfully connected to %s %s" % (whathappened[0],whathappened[1])
to_check -= 1
def failed(reason):
print >>sys.stderr, "Connection to failed : %s" % reason
to_check -= 1
def checked(_):
print >>sys.stdout, "%d connections left to check" % to_check
if to_check == 0:
reactor.stop()
for i in range(0,total):
d = check_conn(ip + str(i),port)
d.addCallbacks(connected,failed)
d.addBoth(checked)
reactor.run()
if __name__ == "__main__":
main()
Run Code Online (Sandbox Code Playgroud)
输出:
Trying Connection to 10.1.1.0 ...
...
...
Trying Connection to 10.1.1.9 ...
Successfully connected to 10.1.1.1 and was prompted for password
10 connections left to check
Successfully connected to 10.1.1.0 and was prompted for password
10 connections left to check
Successfully connected to 10.1.1.2 and was prompted for password
10 connections left to check
Successfully connected to 10.1.1.9 and was prompted for password
10 connections left to check
....{Similar output}
Successfully connected to 10.1.1.6 and was prompted for password
10 connections left to check
Run Code Online (Sandbox Code Playgroud)
要检查的连接数应该减少,但它保持不变.
这是你理解python中闭包的一个普遍问题; 默认情况下,变量是分配它们的最内层函数的本地变量.-=是隐式分配,所以to_check成为局部变量connected和failed.因此,函数to_check中的main函数永远不会改变.在python 3.x中,nonlocal to_check在顶部,connected并将failed使它做你期望的.以下是如何使用2.x中的变异完成同样的事情的示例:
import itertools
def main():
ip = "10.1.1."
port = 23
to_check = 10
counter = itertools.count().next
from twisted.internet import reactor
def connected(whathappened):
print >>sys.stdout, "Successfully connected to %s %s" % (whathappened[0],whathappened[1])
return counter()
def failed(reason):
print >>sys.stderr, "Connection to failed : %s" % reason
return counter()
def checked(count):
print >>sys.stdout, "%d connections left to check" % (to_check - count,)
if count == to_check:
reactor.stop()
for i in range(0,total):
d = check_conn(ip + str(i),port)
d.addCallbacks(connected,failed)
d.addBoth(checked)
reactor.run()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
496 次 |
| 最近记录: |