国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

使用Python的Twisted框架編寫簡單的網絡客戶端

2019-11-25 17:43:37
字體:
來源:轉載
供稿:網友

Protocol
  和服務器一樣,也是通過該類來實現。先看一個簡短的例程:

from twisted.internet.protocol import Protocolfrom sys import stdoutclass Echo(Protocol):  def dataReceived(self, data):    stdout.write(data)

在本程序中,只是簡單的將獲得的數據輸出到標準輸出中來顯示,還有很多其他的事件沒有作出任何響應,下面
有一個回應其他事件的例子:

from twisted.internet.protocol import Protocolclass WelcomeMessage(Protocol):  def connectionMade(self):    self.transport.write("Hello server, I am the client!/r/n")    self.transport.loseConnection()

本協議連接到服務器,發送了一個問候消息,然后關閉了連接。
connectionMade事件通常被用在建立連接的事件發生時觸發。關閉連接的時候會觸發connectionLost事件函數

(Simple, single-use clients)簡單的單用戶客戶端
  在許多情況下,protocol僅僅是需要連接服務器一次,并且代碼僅僅是要獲得一個protocol連接的實例。在
這樣的情況下,twisted.internet.protocol.ClientCreator提供了一個恰當的API

from twisted.internet import reactorfrom twisted.internet.protocol import Protocol, ClientCreatorclass Greeter(Protocol):  def sendMessage(self, msg):    self.transport.write("MESSAGE %s/n" % msg)def gotProtocol(p):  p.sendMessage("Hello")  reactor.callLater(1, p.sendMessage, "This is sent in a second")  reactor.callLater(2, p.transport.loseConnection)c = ClientCreator(reactor, Greeter)c.connectTCP("localhost", 1234).addCallback(gotProtocol)


ClientFactory(客戶工廠)
  ClientFactory負責創建Protocol,并且返回相關事件的連接狀態。這樣就允許它去做像連接發生錯誤然后
重新連接的事情。這里有一個ClientFactory的簡單例子使用Echo協議并且打印當前的連接狀態

from twisted.internet.protocol import Protocol, ClientFactoryfrom sys import stdoutclass Echo(Protocol):  def dataReceived(self, data):    stdout.write(data)class EchoClientFactory(ClientFactory):  def startedConnecting(self, connector):    print 'Started to connect.'    def buildProtocol(self, addr):    print 'Connected.'    return Echo()    def clientConnectionLost(self, connector, reason):    print 'Lost connection. Reason:', reason    def clientConnectionFailed(self, connector, reason):    print 'Connection failed. Reason:', reason

要想將EchoClientFactory連接到服務器,可以使用下面代碼:

from twisted.internet import reactorreactor.connectTCP(host, port, EchoClientFactory())reactor.run()

注意:clientConnectionFailed是在Connection不能被建立的時候調用,clientConnectionLost是在連接關閉的時候被調用,兩個是有區別的。


Reconnection(重新連接)
  許多時候,客戶端連接可能由于網絡錯誤經常被斷開。一個重新建立連接的方法是在連接斷開的時候調用

connector.connect()方法。

from twisted.internet.protocol import ClientFactoryclass EchoClientFactory(ClientFactory):  def clientConnectionLost(self, connector, reason):    connector.connect()

   connector是connection和protocol之間的一個接口被作為第一個參數傳遞給clientConnectionLost,

factory能調用connector.connect()方法重新進行連接
   然而,許多程序在連接失敗和連接斷開進行重新連接的時候使用ReconnectingClientFactory函數代替這個

函數,并且不斷的嘗試重新連接。這里有一個Echo Protocol使用ReconnectingClientFactory的例子:

from twisted.internet.protocol import Protocol, ReconnectingClientFactoryfrom sys import stdoutclass Echo(Protocol):  def dataReceived(self, data):    stdout.write(data)class EchoClientFactory(ReconnectingClientFactory):  def startedConnecting(self, connector):    print 'Started to connect.'  def buildProtocol(self, addr):    print 'Connected.'    print 'Resetting reconnection delay'    self.resetDelay()    return Echo()  def clientConnectionLost(self, connector, reason):    print 'Lost connection. Reason:', reason    ReconnectingClientFactory.clientConnectionLost(self, connector, reason)  def clientConnectionFailed(self, connector, reason):    print 'Connection failed. Reason:', reason    ReconnectingClientFactory.clientConnectionFailed(self, connector,reason)


A Higher-Level Example: ircLogBot
上面的所有例子都非常簡單,下面是一個比較復雜的例子來自于doc/examples目錄

# twisted importsfrom twisted.words.protocols import ircfrom twisted.internet import reactor, protocolfrom twisted.python import log# system importsimport time, sysclass MessageLogger:  """  An independent logger class (because separation of application  and protocol logic is a good thing).  """  def __init__(self, file):    self.file = file  def log(self, message):    """Write a message to the file."""    timestamp = time.strftime("[%H:%M:%S]", time.localtime(time.time()))    self.file.write('%s %s/n' % (timestamp, message))    self.file.flush()  def close(self):    self.file.close()class LogBot(irc.IRCClient):  """A logging IRC bot."""  nickname = "twistedbot"  def connectionMade(self):    irc.IRCClient.connectionMade(self)    self.logger = MessageLogger(open(self.factory.filename, "a"))    self.logger.log("[connected at %s]" %            time.asctime(time.localtime(time.time())))  def connectionLost(self, reason):    irc.IRCClient.connectionLost(self, reason)    self.logger.log("[disconnected at %s]" %            time.asctime(time.localtime(time.time())))    self.logger.close()  # callbacks for events  def signedOn(self):    """Called when bot has succesfully signed on to server."""    self.join(self.factory.channel)  def joined(self, channel):    """This will get called when the bot joins the channel."""    self.logger.log("[I have joined %s]" % channel)  def privmsg(self, user, channel, msg):    """This will get called when the bot receives a message."""    user = user.split('!', 1)[0]    self.logger.log("<%s> %s" % (user, msg))    # Check to see if they're sending me a private message    if channel == self.nickname:      msg = "It isn't nice to whisper! Play nice with the group."      self.msg(user, msg)      return    # Otherwise check to see if it is a message directed at me    if msg.startswith(self.nickname + ":"):      msg = "%s: I am a log bot" % user      self.msg(channel, msg)      self.logger.log("<%s> %s" % (self.nickname, msg))  def action(self, user, channel, msg):    """This will get called when the bot sees someone do an action."""    user = user.split('!', 1)[0]    self.logger.log("* %s %s" % (user, msg))  # irc callbacks  def irc_NICK(self, prefix, params):    """Called when an IRC user changes their nickname."""    old_nick = prefix.split('!')[0]    new_nick = params[0]    self.logger.log("%s is now known as %s" % (old_nick, new_nick))class LogBotFactory(protocol.ClientFactory):  """A factory for LogBots.  A new protocol instance will be created each time we connect to the server.  """  # the class of the protocol to build when new connection is made  protocol = LogBot  def __init__(self, channel, filename):    self.channel = channel    self.filename = filename  def clientConnectionLost(self, connector, reason):    """If we get disconnected, reconnect to server."""    connector.connect()  def clientConnectionFailed(self, connector, reason):    print "connection failed:", reason    reactor.stop()if __name__ == '__main__':  # initialize logging  log.startLogging(sys.stdout)  # create factory protocol and application  f = LogBotFactory(sys.argv[1], sys.argv[2])  # connect factory to this host and port  reactor.connectTCP("irc.freenode.net", 6667, f)  # run bot  reactor.run()

ircLogBot.py 連接到了IRC服務器,加入了一個頻道,并且在文件中記錄了所有的通信信息,這表明了在斷開連接進行重新連接的連接級別的邏輯以及持久性數據是被存儲在Factory的。

Persistent Data in the Factory
  由于Protocol在每次連接的時候重建,客戶端需要以某種方式來記錄數據以保證持久化。就好像日志機器人一樣他需要知道那個那個頻道正在登陸,登陸到什么地方去。

from twisted.internet import protocolfrom twisted.protocols import ircclass LogBot(irc.IRCClient):  def connectionMade(self):    irc.IRCClient.connectionMade(self)    self.logger = MessageLogger(open(self.factory.filename, "a"))    self.logger.log("[connected at %s]" %            time.asctime(time.localtime(time.time())))    def signedOn(self):    self.join(self.factory.channel)  class LogBotFactory(protocol.ClientFactory):    protocol = LogBot    def __init__(self, channel, filename):    self.channel = channel    self.filename = filename

當protocol被創建之后,factory會獲得他本身的一個實例的引用。然后,就能夠在factory中存在他的屬性。

更多的信息:
  本文檔講述的Protocol類是IProtocol的子類,IProtocol方便的被應用在大量的twisted應用程序中。要學習完整的 IProtocol接口,請參考API文檔IProtocol.
  在本文檔一些例子中使用的trasport屬性提供了ITCPTransport接口,要學習完整的接口,請參考API文檔ITCPTransport
  接口類是指定對象有什么方法和屬性以及他們的表現形式的一種方法。參考 Components: Interfaces and Adapters文檔

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 武强县| 扎鲁特旗| 长武县| 茌平县| 浪卡子县| 昔阳县| 丰宁| 自治县| 正阳县| 崇礼县| 武宣县| 响水县| 龙门县| 潞西市| 朔州市| 卢湾区| 隆德县| 措勤县| 高雄县| 鄯善县| 洛阳市| 铁岭县| 门源| 兴文县| 通州区| 中方县| 呼玛县| 库伦旗| 金华市| 伊宁市| 吉安县| 黄陵县| 岳普湖县| 蚌埠市| 鹤壁市| 清流县| 望谟县| 新野县| 邵东县| 万全县| 闸北区|