我有以下代码,客户端每隔8秒就会向服务器发送一些数据,以下是我的代码
class EchoClient(LineReceiver):
def connectionMade(self):
makeByteList()
self.transport.write(binascii.unhexlify("7777"))
while 1:
print "hello"
lep = random.randint(0,4)
print lep
print binascii.unhexlify(sendHexBytes(lep))
try:
self.transport.write("Hello")
self.transport.write(binascii.unhexlify(sendHexBytes(lep)))
except Exception, ex1:
print "Failed to send"
time.sleep(8)
def lineReceived(self, line):
pass
def dataReceived(self, data):
print "receive:", data
while循环中的每个语句都执行除self.transport.write之外。服务器不接收任何数据。另外self.transport.write while while循环不执行。在这两种情况下都不会引发异常,但如果我删除while循环,则循环外的语句将正确执行。为什么会这样?请纠正我错误的地方?
答案 0 :(得分:3)
扭曲的所有方法都是异步。 connectionMade
和lineReceived
等所有方法都发生在同一个线程上。 Twisted反应器运行一个循环(称为事件循环),当这些事件发生时,它会调用诸如connectionMade
和lineReceived
之类的方法。
connectionMade
中有一个无限循环。一旦Python进入该循环,它就永远不会消失。建立连接后,您可以使用Twisted调用connectionMade
,并且您的代码永远存在。 Twisted没有机会将数据实际写入传输或接收数据,它被卡在connectionMade
!
当您编写Twisted代码时,您必须了解的重点是您可能不会在Twisted线程上阻止。例如,假设我想在客户端连接后4秒发送“Hello”。我可以这样写:
class EchoClient(LineReceiver):
def connectionMade(self):
time.sleep(4)
self.transport.write("Hello")
但这是错误的。如果2个客户端同时连接会发生什么?第一个客户端将进入connectionMade
,我的程序将挂起4秒,直到发送“Hello”。
扭曲的方式是这样的:
class EchoClient(LineReceiver):
def connectionMade(self):
reactor.callLater(4, self.sendHello)
def sendHello(self):
self.transport.write("Hello")
现在,当Twisted进入connectionMade
时,它会在未来4秒内调用reactor.callLater
计划一个事件。然后它退出connectionMade
并继续完成它需要做的所有其他事情。在你掌握异步编程的概念之前,你无法继续使用Twisted。我建议你仔细阅读Twisted docs here。
最后,一个不相关的说明:如果您有LineReceiver
,则不应实施自己的dataReceived
,否则会调用lineReceived
。 LineReceiver
是一个协议,它实现了自己的dataReceived
,它将数据缓冲并分解为行并调用lineReceived
方法。