Twisted Socket立即发送消息

时间:2012-05-20 00:36:19

标签: python twisted

我正在创建一个与Twisted套接字通信的iPhone应用程序,当我有一条要发送的消息时它很有用。但是,我的问题是我需要向应用程序发送许多不同的信息。这是我的代码。

            if numrows == 1:
                #Did login
                msg = "%s: Login Credentials Success" % _UDID
                print msg
                for c in self.factory.clients:
                    c.message(msg)
                    time.sleep(0.5)

                for result in results:
                    for i in range(1, 6):
                        msg = "%s:L%d;%s" % (_UDID, i, result[i])
                        print msg
                        for c in self.factory.clients:
                            c.message(msg)
                            time.sleep(0.5)
            else:
                msg = "%s: Login Credentials Failed" % _UDID
                print msg
                for c in self.factory.clients:
                    c.message(msg)
                    time.sleep(0.5)

            cursor.close()
            database.close()

        #print msg

        #for c in self.factory.clients:
            #c.message(msg)

def message(self, message):
    self.transport.write(message)

假设我只发送第一个消息,并且每个其他消息都不存在以及每个消息下面的方法,消息Login Credentials Success将被发送到应用程序。但是,如果把它放在其余部分就像你看到它一样,没有什么可以发生,因为它会立即发送所有内容,即使在代码中放入了一个time.sleep。

应用程序每0.5秒或更短时间检查一次响应。尽管登录凭据位于顶部,但它没有通过,因为之后发送了更多信息,但是在凭证消息之后没有所有信息,它将会通过。

我迫切希望找到答案。我已经尝试了所有我能想到的东西。应用程序不是问题,它是Python。

感谢。

2 个答案:

答案 0 :(得分:2)

冒着因为矛盾而冒犯的风险,您可能需要重新检查您的应用不是问题的说法。听起来您希望能够完全控制每个传出TCP数据包的内容,并且您的应用程序取决于数据包边界以确定消息边界。这对于网络来说不是一个非常好的方法;一些网络中介可能会分开(碎片)甚至整合数据包,这会使您的应用程序混淆。请记住, TCP不是数据包协议:它是一种流协议,因此您只能保证您发送的八位字节将按顺序接收,如果有的话。

处理不同大小的消息的常用方法是在每个消息前面加上一个X位大端字段字段,说明后续消息的大小。通信的接收端首先读取X位,然后读取“大小”八位字节以获取完整的消息(阻塞直到该点,并在缓冲区中留下任何其他信息以供下一个消息处理程序获取)。

我不介意使用Twisted代码进行更多帮助,但很可能它已经正确编写了。至少,我建议不要立即尝试制作Twisted flush网络写缓冲区。虽然它可能有助于使您的代码看起来正常工作,但它实际上只是隐藏了稍后会出现的问题。

答案 1 :(得分:1)

您的问题似乎是Twisted缓冲您写入的数据。

显然,没有简单的方法可以强制数据自行发送而无需重构大量代码。请参阅Twisted transport.writeUsing Twisted's twisted.web classes, how do I flush my outgoing buffers?

根据上一个链接的接受答案,在不知道你的代码看起来像你粘贴之前的代码:

  • 定义wait函数,就像在接受的答案中一样
  • 确保您的班级继承自http.Request
  • 使用message
  • 装饰您的方法defer.inlineCallbacks
  • yield wait(N)方法
  • 上调用write后,添加message(您必须测试并确定的值为N)

我没有足够的经验与Twisted知道哪些步骤是必需的,哪些只是原始答案的代码不适用于您的代码。

然而,重写iPhone应用程序以接受在单个消息中包含多个写入时发送的消息类型可能(并且更容易)。