激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Python - 使用Python的Twisted框架編寫簡單的網絡客戶端

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

2020-06-07 10:43Python教程網 Python

這篇文章主要介紹了使用Python的Twisted框架編寫簡單的網絡客戶端,翻譯自Twisted文檔,包括一個簡單的IRC客戶端的實現,需要的朋友可以參考下

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

?
1
2
3
4
5
6
from twisted.internet.protocol import Protocol
from sys import stdout
 
class Echo(Protocol):
  def dataReceived(self, data):
    stdout.write(data)

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

?
1
2
3
4
5
6
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()

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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(客戶工廠)
  ClientFactory負責創建Protocol,并且返回相關事件的連接狀態。這樣就允許它去做像連接發生錯誤然后
重新連接的事情。這里有一個ClientFactory的簡單例子使用Echo協議并且打印當前的連接狀態

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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連接到服務器,可以使用下面代碼:

?
1
2
3
from twisted.internet import reactor
reactor.connectTCP(host, port, EchoClientFactory())
reactor.run()

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


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

connector.connect()方法。

?
1
2
3
4
5
from twisted.internet.protocol import ClientFactory
 
class EchoClientFactory(ClientFactory):
  def clientConnectionLost(self, connector, reason):
    connector.connect()

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

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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
上面的所有例子都非常簡單,下面是一個比較復雜的例子來自于doc/examples目錄

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# 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服務器,加入了一個頻道,并且在文件中記錄了所有的通信信息,這表明了在斷開連接進行重新連接的連接級別的邏輯以及持久性數據是被存儲在Factory的。

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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

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

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

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25
主站蜘蛛池模板: 我爱我色成人网 | 性欧美在线视频 | 欧美激情图区 | 91精品福利视频 | 国内精品国产三级国产a久久 | 欧美成人理论片乱 | 国产成人高清成人av片在线看 | 成人性视频欧美一区二区三区 | 99在线热视频 | 桥本有菜免费av一区二区三区 | 亚洲影视在线观看 | 综合精品一区 | 国产一区影院 | 亚洲一区二区三区高清 | 天天草天天干天天射 | 日本a大片 | 天天色综合2 | 免费a级片在线观看 | 国产成人小视频在线观看 | 美女视频免费一区二区 | 欧美77| www.99re14.com| 全黄性性激高免费视频 | 国产成人在线一区二区 | 成人毛片视频在线播放 | 精品久久久久久国产三级 | 欧美日韩国产成人在线观看 | 国产精品久久久久久久久久10秀 | 亚洲第一页综合 | av电影在线免费观看 | 久久老司机| 韩国一级免费视频 | 草莓视频久久 | 18视频在线观看娇喘 | 欧美www | 国产成人在线免费视频 | 精品一区二区三区电影 | 日本网站一区二区三区 | 久久99精品久久久久久236 | av成人在线电影 | 国产妇女乱码一区二区三区 |