使用Python的Twisted框架编写简单的网络客户端
|
Protocol
from twisted.internet.protocol import Protocol
from sys import stdout
class Echo(Protocol):
def dataReceived(self,data):
stdout.write(data)
在本程序中,只是简单的将获得的数据输出到标准输出中来显示,还有很多其他的事件没有作出任何响应,下面
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()
本协议连接到服务器,发送了一个问候消息,然后关闭了连接。 (Simple,single-use clients)简单的单用户客户端
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)
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,reason):
print 'Connection failed. Reason:',reason
要想将EchoClientFactory连接到服务器,可以使用下面代码: from twisted.internet import reactor reactor.connectTCP(host,port,EchoClientFactory()) reactor.run() 注意:clientConnectionFailed是在Connection不能被建立的时候调用,clientConnectionLost是在连接关闭的时候被调用,两个是有区别的。
connector.connect()方法。
from twisted.internet.protocol import ClientFactory
class EchoClientFactory(ClientFactory):
def clientConnectionLost(self,reason):
connector.connect()
connector是connection和protocol之间的一个接口被作为第一个参数传递给clientConnectionLost, factory能调用connector.connect()方法重新进行连接 函数,并且不断的尝试重新连接。这里有一个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,reason
ReconnectingClientFactory.clientConnectionLost(self,reason)
def clientConnectionFailed(self,reason
ReconnectingClientFactory.clientConnectionFailed(self,reason)
# 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,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,filename):
self.channel = channel
self.filename = filename
def clientConnectionLost(self,reason):
"""If we get disconnected,reconnect to server."""
connector.connect()
def clientConnectionFailed(self,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
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,filename):
self.channel = channel
self.filename = filename
当protocol被创建之后,factory会获得他本身的一个实例的引用。然后,就能够在factory中存在他的属性。 (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
