最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用Python的Twisted框架編寫(xiě)簡(jiǎn)單的網(wǎng)絡(luò)客戶(hù)端

 更新時(shí)間:2015年04月16日 09:42:06   投稿:goldensun  
這篇文章主要介紹了使用Python的Twisted框架編寫(xiě)簡(jiǎn)單的網(wǎng)絡(luò)客戶(hù)端,翻譯自Twisted文檔,包括一個(gè)簡(jiǎn)單的IRC客戶(hù)端的實(shí)現(xiàn),需要的朋友可以參考下

Protocol
  和服務(wù)器一樣,也是通過(guò)該類(lèi)來(lái)實(shí)現(xiàn)。先看一個(gè)簡(jiǎn)短的例程:

from twisted.internet.protocol import Protocol
from sys import stdout

class Echo(Protocol):
  def dataReceived(self, data):
    stdout.write(data)

在本程序中,只是簡(jiǎn)單的將獲得的數(shù)據(jù)輸出到標(biāo)準(zhǔn)輸出中來(lái)顯示,還有很多其他的事件沒(méi)有作出任何響應(yīng),下面
有一個(gè)回應(yīng)其他事件的例子:

from twisted.internet.protocol import Protocol

class WelcomeMessage(Protocol):
  def connectionMade(self):
    self.transport.write("Hello server, I am the client!/r/n")
    self.transport.loseConnection()

本協(xié)議連接到服務(wù)器,發(fā)送了一個(gè)問(wèn)候消息,然后關(guān)閉了連接。
connectionMade事件通常被用在建立連接的事件發(fā)生時(shí)觸發(fā)。關(guān)閉連接的時(shí)候會(huì)觸發(fā)connectionLost事件函數(shù)

(Simple, single-use clients)簡(jiǎn)單的單用戶(hù)客戶(hù)端
  在許多情況下,protocol僅僅是需要連接服務(wù)器一次,并且代碼僅僅是要獲得一個(gè)protocol連接的實(shí)例。在
這樣的情況下,twisted.internet.protocol.ClientCreator提供了一個(gè)恰當(dāng)?shù)腁PI

from twisted.internet import reactor
from twisted.internet.protocol import Protocol, ClientCreator

class 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(客戶(hù)工廠)
  ClientFactory負(fù)責(zé)創(chuàng)建Protocol,并且返回相關(guān)事件的連接狀態(tài)。這樣就允許它去做像連接發(fā)生錯(cuò)誤然后
重新連接的事情。這里有一個(gè)ClientFactory的簡(jiǎn)單例子使用Echo協(xié)議并且打印當(dāng)前的連接狀態(tài)

from twisted.internet.protocol import Protocol, ClientFactory
from sys import stdout

class 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連接到服務(wù)器,可以使用下面代碼:

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

注意:clientConnectionFailed是在Connection不能被建立的時(shí)候調(diào)用,clientConnectionLost是在連接關(guān)閉的時(shí)候被調(diào)用,兩個(gè)是有區(qū)別的。


Reconnection(重新連接)
  許多時(shí)候,客戶(hù)端連接可能由于網(wǎng)絡(luò)錯(cuò)誤經(jīng)常被斷開(kāi)。一個(gè)重新建立連接的方法是在連接斷開(kāi)的時(shí)候調(diào)用

connector.connect()方法。

from twisted.internet.protocol import ClientFactory

class EchoClientFactory(ClientFactory):
  def clientConnectionLost(self, connector, reason):
    connector.connect()

   connector是connection和protocol之間的一個(gè)接口被作為第一個(gè)參數(shù)傳遞給clientConnectionLost,

factory能調(diào)用connector.connect()方法重新進(jìn)行連接
   然而,許多程序在連接失敗和連接斷開(kāi)進(jìn)行重新連接的時(shí)候使用ReconnectingClientFactory函數(shù)代替這個(gè)

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

from twisted.internet.protocol import Protocol, ReconnectingClientFactory
from sys import stdout

class 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
上面的所有例子都非常簡(jiǎn)單,下面是一個(gè)比較復(fù)雜的例子來(lái)自于doc/examples目錄

# twisted imports
from twisted.words.protocols import irc
from twisted.internet import reactor, protocol
from twisted.python import log

# system imports
import time, sys


class 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服務(wù)器,加入了一個(gè)頻道,并且在文件中記錄了所有的通信信息,這表明了在斷開(kāi)連接進(jìn)行重新連接的連接級(jí)別的邏輯以及持久性數(shù)據(jù)是被存儲(chǔ)在Factory的。

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

from twisted.internet import protocol
from twisted.protocols import irc

class 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

當(dāng)protocol被創(chuàng)建之后,factory會(huì)獲得他本身的一個(gè)實(shí)例的引用。然后,就能夠在factory中存在他的屬性。

更多的信息:
  本文檔講述的Protocol類(lèi)是IProtocol的子類(lèi),IProtocol方便的被應(yīng)用在大量的twisted應(yīng)用程序中。要學(xué)習(xí)完整的 IProtocol接口,請(qǐng)參考API文檔IProtocol.
  在本文檔一些例子中使用的trasport屬性提供了ITCPTransport接口,要學(xué)習(xí)完整的接口,請(qǐng)參考API文檔ITCPTransport
  接口類(lèi)是指定對(duì)象有什么方法和屬性以及他們的表現(xiàn)形式的一種方法。參考 Components: Interfaces and Adapters文檔

相關(guān)文章

  • python實(shí)現(xiàn)詩(shī)歌游戲(類(lèi)繼承)

    python實(shí)現(xiàn)詩(shī)歌游戲(類(lèi)繼承)

    這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)詩(shī)歌游戲,根據(jù)上句猜下句、猜作者、猜朝代、猜詩(shī)名,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-02-02
  • Python中ModuleNotFoundError: No module named ‘timm’的錯(cuò)誤解決

    Python中ModuleNotFoundError: No module named&n

    本文主要介紹了Python中ModuleNotFoundError: No module named ‘timm’的錯(cuò)誤解決,錯(cuò)誤意味著你的Python環(huán)境中沒(méi)有安裝名為“timm”的模塊,下面就介紹一下幾種解決方法,感興趣的可以了解一下
    2025-03-03
  • 解決安裝新版PyQt5、PyQT5-tool后打不開(kāi)并Designer.exe提示no Qt platform plugin的問(wèn)題

    解決安裝新版PyQt5、PyQT5-tool后打不開(kāi)并Designer.exe提示no Qt platform plug

    這篇文章主要介紹了解決安裝新版PyQt5、PyQT5-tool后打不開(kāi)并Designer.exe提示no Qt platform plugin的問(wèn)題,需要的朋友可以參考下
    2020-04-04
  • 在Pycharm中修改文件默認(rèn)打開(kāi)方式的方法

    在Pycharm中修改文件默認(rèn)打開(kāi)方式的方法

    今天小編就為大家分享一篇在Pycharm中修改文件默認(rèn)打開(kāi)方式的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-01-01
  • python使用OS模塊操作系統(tǒng)接口及常用功能詳解

    python使用OS模塊操作系統(tǒng)接口及常用功能詳解

    os是?Python?標(biāo)準(zhǔn)庫(kù)中的一個(gè)模塊,提供了與操作系統(tǒng)交互的功能,在本節(jié)中,我們將介紹os模塊的一些常用功能,并通過(guò)實(shí)例代碼詳細(xì)講解每個(gè)知識(shí)點(diǎn)
    2023-06-06
  • Python+decimal完成精度計(jì)算的示例詳解

    Python+decimal完成精度計(jì)算的示例詳解

    在進(jìn)行小數(shù)計(jì)算的時(shí)候使用float,經(jīng)常會(huì)出現(xiàn)小數(shù)位不精確的情況。在python編程中,推薦使用decimal來(lái)完成小數(shù)位的精度計(jì)算。本文將通過(guò)示例詳細(xì)說(shuō)說(shuō)decimal的使用,需要的可以參考一下
    2022-10-10
  • Python+turtle繪制七夕表白玫瑰花

    Python+turtle繪制七夕表白玫瑰花

    七夕節(jié),又稱(chēng)“七巧節(jié)”“女兒節(jié)”“乞巧節(jié)”等,是中國(guó)民間的傳統(tǒng)節(jié)日。一年一度的七夕又快到了,用Python畫(huà)一朵玫瑰花送給你的那個(gè)TA吧
    2022-08-08
  • 一文詳解Python中實(shí)現(xiàn)單例模式的幾種常見(jiàn)方式

    一文詳解Python中實(shí)現(xiàn)單例模式的幾種常見(jiàn)方式

    這篇文章主要為大家介紹了Python中實(shí)現(xiàn)單例模式的幾種常見(jiàn)方式示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • Python學(xué)習(xí)之文件的讀取詳解

    Python學(xué)習(xí)之文件的讀取詳解

    這篇文章主要為大家介紹了Python中如何將文件中的內(nèi)容讀取出去來(lái)的方法,文中通過(guò)示例進(jìn)行了詳細(xì)講解,感興趣的小伙伴快跟隨小編一起學(xué)習(xí)一下
    2022-03-03
  • 解決AttributeError:'NoneTypeobject'?has?no?attribute'Window'的問(wèn)題(親測(cè)有效)

    解決AttributeError:'NoneTypeobject'?has?no?attrib

    這篇文章主要介紹了解決AttributeError:?‘NoneType‘?object?has?no?attribute?‘Window‘的問(wèn)題(親測(cè)有效),本文給大家介紹的非常想詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-03-03

最新評(píng)論

威信县| 宜宾县| 通河县| 叶城县| 正安县| 乌拉特后旗| 武宣县| 镇坪县| 孟州市| 克东县| 正阳县| 江安县| 武山县| 郴州市| 兴义市| 米林县| 广平县| 基隆市| 牡丹江市| 安西县| 萝北县| 霍邱县| 济源市| 如皋市| 聊城市| 额济纳旗| 宣威市| 新邵县| 洞头县| 乐清市| 股票| 金川县| 德兴市| 玛多县| 鹤峰县| 富宁县| 天峨县| 松原市| 灵武市| 蓝山县| 张北县|