一个echo服务器和客户端的实例,基本照着书抄的.
如果用过socket写过类似最简单东西应该很好理解,没写过的话就不好办了。
不过要是想深入了解一下twsited框架还是需要了解很多东西,比如异步,多线程等等,慢慢深入吧,
不然,只能做一些很简单无法用于生产的Echo。
EchoServer And Client.
EchoServer.py:
from twisted.internet import protocol, reactor import sys class Echo(protocol.Protocol): # re-write the dataReceived method def dataReceived(self, data): # get the peer of the connection addr = self.transport.getPeer() msg_from_client = str(addr) + " send " + data sys.stdout.write(msg_from_client) self.transport.write(data) class EchoFactory(protocol.Factory): def buildProtocol(self, addr): return Echo() reactor.listenTCP(12345, EchoFactory()) reactor.run()
Client.py:
from twisted.internet import reactor, protocol class EchoClient(protocol.Protocol): # re-write the connectionMade method def connectionMade(self): self.transport.write("Hello, I am client!") def dataReceived(self, data): print "Server said:", data self.transport.loseConnection() print "Lost Connection..." class EchoFactory(protocol.ClientFactory): def buildProtocol(self, addr): return EchoClient() def clientConnectionFailed(self, connector, reason): print "Connection Failed..." reactor.stop() def clientConnectionLost(self, connector, reason): print "Connection Lost..." reactor.stop() reactor.connectTCP('localhost', 12345, EchoFactory()) reactor.run()
可以看出来,twsited框架的使用很简单,而且是面向对象的,那么我们得看看那些东西是框架自带的,哪些是自己可以扩展的。
twsited-fun.py:
from twisted.internet import protocol print dir(protocol.Protocol)
就可以知道protocol.Protocol到底有哪些属性和方法了。在EchoServer里,只是重写了dataRecived方法,并调用了transport的getPeer()方法得到
对方的地址信息,其中transport就是服务器和客户端直接的连接,还使用了write用于将信息发送给对端,然后把一些信息输出到stdout。
另外,Protocol Factories表示一个抽象的协议组,在定义buildProtocol时就定义了连接时的事件,同时向reactor注册回调函数。
同样,在EchoClient里,重写了connectionMade(),用来定义连接发生时候的行为,dataRecived()定义接收到数据的行为,而在
EchoFactory中也一样重写了clientConnectionFailed()和clientConnectionLost()用于响应连接失败和关闭的行为。
一个类似传话筒的应用,Client向Server传话,Client也接受Server的传话,Server将Client传来的保存起来,然后再传给下一个Client.
qserver.py:
#!/usr/bin/env python # -*- coding: utf-8 -*- from twisted.internet import reactor, protocol class QuoteProtocol(protocol.Protocol): def __init__(self, factory): self.factory = factory def connectionMade(self): self.factory.numConnections += 1 # 将接受到的信息保存下来,下次再发出去。 def dataReceived(self, data): print "Number of active connections: %d" % ( self.factory.numConnections,) print "> Received: ``%s''\n> Sending: ``%s''" % ( data, self.getQuote()) self.transport.write(self.getQuote()) self.updateQuote(data) def connectionLost(self, reason): self.factory.numConnections -= 1 def getQuote(self): return self.factory.quote def updateQuote(self, quote): self.factory.quote = quote class QuoteFactory(protocol.Factory): numConnections = 0 def __init__(self, quote=None): self.quote = quote or "An apple a day keeps the doctor away" def buildProtocol(self, addr): return QuoteProtocol(self) reactor.listenTCP(54321, QuoteFactory()) reactor.run()
qclient.py:
#!/usr/bin/env python # -*- coding: utf-8 -*- from twisted.internet import reactor, protocol class QuoteProtocol(protocol.Protocol): def __init__(self, factory): self.factory = factory def connectionMade(self): self.sendQuote() # 发送出去信息 def sendQuote(self): self.transport.write(self.factory.quote) # 接受到信息后结束连接 def dataReceived(self, data): print "Received quote:", data self.transport.loseConnection() class QuoteClientFactory(protocol.ClientFactory): def __init__(self, quote): self.quote = quote def buildProtocol(self, addr): return QuoteProtocol(self) def clientConnectionFailed(self, connector, reason): print 'connection failed:', reason.getErrorMessage() maybeStopReactor() def clientConnectionLost(self, connector, reason): print 'connection lost:', reason.getErrorMessage() maybeStopReactor() # 定义结束reactor的条件 def maybeStopReactor(): global quote_counter quote_counter -= 1 if not quote_counter: reactor.stop() quotes = [ "You snooze you lose", "The early bird gets the worm", "Carpe diem" ] quote_counter = len(quotes) for quote in quotes: reactor.connectTCP('localhost', 54321, QuoteClientFactory(quote)) reactor.run()
代码基本上很容易理解。重定义好了事件处理函数就行了。