2

我正在制作一个与 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)

假设我只发送第一个 msg,并且所有其他 msg 与 print 和每个 msg 下面的方法都不存在,消息 Login Credentials Success 将被发送到应用程序。但是,如果像您看到的那样放入其余部分,则不会发生任何事情,因为它会一次发送所有内容,即使在代码中添加 time.sleep 也是如此。

该应用程序每 0.05 秒或更短时间检查一次响应。即使登录凭据位于顶部,它也不会通过,因为之后会发送更多信息,但是如果没有凭据消息之后的所有信息,它也会通过。

我迫不及待地想找到这个问题的答案。我已经尝试了我能想到的一切。应用程序不是问题,是 Python。

谢谢。

4

2 回答 2

2

冒着矛盾冒犯的风险,您可能需要重新检查您的应用程序不是问题的说法。听起来您希望完全控制每个传出 TCP 数据包的内容,并且您的应用程序依赖数据包边界来确定消息边界。一般来说,这不是一个很好的联网方法。一些网络中介可能会在此过程中拆分(碎片)甚至合并数据包,这会使您的应用程序感到困惑。请记住,TCP 不是数据包协议:它是流协议,因此您只能真正保证您发送的八位字节将按顺序接收(如果有的话)。

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

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

于 2012-05-21T19:00:09.373 回答
1

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

显然,在不重构大量代码的情况下,没有简单的方法可以强制数据自行发送。请参阅Twisted transport.write使用 Twisted 的 twisted.web 类,如何刷新传出缓冲区?.

在粘贴之前不知道您的代码是什么样的,并且根据最后一个链接的接受答案:

  • wait就像在接受的答案中一样定义函数
  • 确保你的类继承自http.Request
  • 装饰你的message方法defer.inlineCallbacks
  • 在调用方法后添加yield wait(N)(对于您必须测试和确定的 N 值)writemessage

我对 Twisted 没有足够的经验,无法知道需要哪些步骤,哪些只是原始答案的代码中的一部分,不适用于您的代码。

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

于 2012-05-20T00:59:32.347 回答