twisted框架入门笔记(1)

一个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''
>  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()

代码基本上很容易理解。重定义好了事件处理函数就行了。

原文地址:https://www.cnblogs.com/jaw-crusher/p/3507859.html