Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python twisted:函数调用不正确?_Python_Client_Twisted_Irc - Fatal编程技术网

Python twisted:函数调用不正确?

Python twisted:函数调用不正确?,python,client,twisted,irc,Python,Client,Twisted,Irc,我在设置连接到“分发服务器”以发送特定数据的客户端时遇到问题。 服务器的目的是从客户端获取数据,然后将数据发送到所有连接的客户端。服务器工作时没有任何问题。 主客户端也应该作为IRC bot工作。 下面是一个文本示例,说明它的工作原理: 约翰:你好 一,。IRC客户端收到消息,我们需要立即将其发送给分发服务器 二,。分发服务器应获取此“John:您好!”字符串,并将其发送回所有已连接的客户端 三,。如果其他客户端向分发服务器发送数据,这将广播给所有客户端,IRC客户端应将接收到的数据输出到指定的

我在设置连接到“分发服务器”以发送特定数据的客户端时遇到问题。 服务器的目的是从客户端获取数据,然后将数据发送到所有连接的客户端。服务器工作时没有任何问题。 主客户端也应该作为IRC bot工作。 下面是一个文本示例,说明它的工作原理:

约翰:你好

一,。IRC客户端收到消息,我们需要立即将其发送给分发服务器

二,。分发服务器应获取此“John:您好!”字符串,并将其发送回所有已连接的客户端

三,。如果其他客户端向分发服务器发送数据,这将广播给所有客户端,IRC客户端应将接收到的数据输出到指定的通道

以下代码是IRC bot客户端(ircbot.py):

我希望客户端将所有传入的聊天数据从IRC服务器输出到“分发服务器”服务器,并从“分发服务器”输出传入的数据。 但是,我会遇到如下错误:

def signedOn(self):
    self.msg("NickServ", "id <password_removed>") # Identify the bot
    time.sleep(0.1) # Wait a little...
    self.join(self.factory.channel) # Join channel #chantest
    print "Signed on as %s." % (self.nickname,)
def buildProtocol(self, addr):
    print 'Connected to the Distributor'
    self.connection = EchoClient()
    return self.connection
对于ircbot.py中的以下行

EchoClient().sendData('IRC'+' '.join(map(str, [name, msg])))
我得到以下错误:

Joined #chantest.
Longdouble: test
Traceback (most recent call last):
  File "C:\Python\lib\site-packages\twisted\internet\tcp.py", line 460, in doRea
d
    return self.protocol.dataReceived(data)
  File "C:\Python\lib\site-packages\twisted\words\protocols\irc.py", line 2277,
in dataReceived
    basic.LineReceiver.dataReceived(self, data.replace('\r', ''))
  File "C:\Python\lib\site-packages\twisted\protocols\basic.py", line 564, in da
taReceived
    why = self.lineReceived(line)
  File "C:\Python\lib\site-packages\twisted\words\protocols\irc.py", line 2285,
in lineReceived
    self.handleCommand(command, prefix, params)
--- <exception caught here> ---
  File "C:\Python\lib\site-packages\twisted\words\protocols\irc.py", line 2329,
in handleCommand
    method(prefix, params)
  File "C:\Python\lib\site-packages\twisted\words\protocols\irc.py", line 1813,
in irc_PRIVMSG
    self.privmsg(user, channel, message)
  File "C:\Python\Traance\kwlbot\ircbot.py", line 51, in privmsg
    EchoClient().sendData('IRC'+' '.join(map(str, [name, msg])))
  File "C:\Python\Traance\kwlbot\ircbot.py", line 90, in sendData
    self.transport.write(data)
exceptions.AttributeError: 'NoneType' object has no attribute 'write'
->

我做错了什么?如何从IRCbot类调用正确的函数,使其将数据发送到分发服务器,并将从分发服务器接收到的数据通过IRC输出到指定的通道

欢迎提出任何建议和可能的解决方案

如果我遗漏了任何其他细节,请告诉我


谢谢你抽出时间

TFM
从未在您的代码中定义,因此我不知道有什么交易

另一个错误是,您正在实例化一个客户端,但从未将其连接到任何东西,如
reactor.connectTCP(…)
endpoint.connect(…)
transport
属性将为
None
,直到它被某个设置


(这将有助于您找到一个更简单的代码版本,它是完整的,不包括所有打印的日志消息等不必要的细节。这将使您更难看到真正的问题。)

您应该避免编写这样的阻塞代码:

def signedOn(self):
    self.msg("NickServ", "id <password_removed>") # Identify the bot
    time.sleep(0.1) # Wait a little...
    self.join(self.factory.channel) # Join channel #chantest
    print "Signed on as %s." % (self.nickname,)
def buildProtocol(self, addr):
    print 'Connected to the Distributor'
    self.connection = EchoClient()
    return self.connection
您正在创建一个协议实例,该实例负责处理连接,然后尝试使用它,但您没有创建连接。发送数据的尝试失败,因为协议尚未连接到任何传输

您的代码片段已经两次演示了创建连接的正确方法:

IRC = BotFactory('#chantest')
reactor.connectTCP('irc.rizon.net', 6667, IRC) # Our IRC connection
f = EchoFactory()
reactor.connectTCP("localhost", 8000, f) # Connection to the Distributor server
错误在于创建一个新的
EchoClient
实例,一个没有连接的实例。
reactor.connectTCP
调用创建一个新连接和一个新的
EchoClient
实例,并将它们彼此关联起来

您希望使用工厂创建的
EchoClient
实例,而不是
EchoClient().sendData(…)

def buildProtocol(self, addr):
    print 'Connected to the Distributor'
    return EchoClient()
您的
buildProtocol
实现创建了该实例,所缺少的只是保存该实例,以便您的IRC bot可以使用它

考虑一下这样的情况:

def signedOn(self):
    self.msg("NickServ", "id <password_removed>") # Identify the bot
    time.sleep(0.1) # Wait a little...
    self.join(self.factory.channel) # Join channel #chantest
    print "Signed on as %s." % (self.nickname,)
def buildProtocol(self, addr):
    print 'Connected to the Distributor'
    self.connection = EchoClient()
    return self.connection
然后,您的IRC客户端可以使用保存的
EchoClient
实例:

    if channel == "#testchan" and name != "BotName":
        f.connection.sendData('IRC:'+' '.join(map(str, [name, msg])))
        # This should make the bot send chat data to the distributor server (NOT IRC server)
请注意,我在这里给出的特定代码是一种非常粗糙的方法。它使用全局变量
f
查找
EchoFactory
实例。与大多数全局变量用法一样,这使得代码有点难以理解。此外,我还没有添加任何代码来处理
connectionLost
事件以清除
connection
属性。这意味着您可能认为您正在向分布式服务器发送数据,而连接已经丢失。同样,无法保证到分布式服务器的连接在IRC客户端首次尝试使用它时已经创建,因此当它尝试使用
f.connection.sendData
时,您可能有一个
AttributeError


然而,修复这些问题并不需要很大的飞跃。修复全局变量的用法,就像修复任何其他变量一样-通过向函数传递参数、将对象保存为其他对象上的引用等。通过处理它或在创建分布式连接之前不创建IRC连接来修复可能的
AttributeError
,等等,通过将属性值重置为
None
或其他sentinel来处理丢失的连接,并在尝试使用分布式客户端连接发送任何数据之前注意IRC代码中的这种情况。

我不知道这是否只是巧合,但是在
sendData
中引发第一个错误的行没有正确缩进。@mac:我认为这与
sendData
没有多大关系,但是这些函数不想以某种方式相互“通信”,因此它们可以将接收到的数据发送到与“活动”服务器不同的服务器谢谢!现在一切都清楚了,事实上,我在弄清楚之后,就成功了。
    if channel == "#testchan" and name != "BotName":
        f.connection.sendData('IRC:'+' '.join(map(str, [name, msg])))
        # This should make the bot send chat data to the distributor server (NOT IRC server)