我正在创建一个与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。
感谢。
答案 0 :(得分:2)
冒着因为矛盾而冒犯的风险,您可能需要重新检查您的应用不是问题的说法。听起来您希望能够完全控制每个传出TCP数据包的内容,并且您的应用程序取决于数据包边界以确定消息边界。这对于网络来说不是一个非常好的方法;一些网络中介可能会分开(碎片)甚至整合数据包,这会使您的应用程序混淆。请记住, TCP不是数据包协议:它是一种流协议,因此您只能保证您发送的八位字节将按顺序接收,如果有的话。
处理不同大小的消息的常用方法是在每个消息前面加上一个X位大端字段字段,说明后续消息的大小。通信的接收端首先读取X位,然后读取“大小”八位字节以获取完整的消息(阻塞直到该点,并在缓冲区中留下任何其他信息以供下一个消息处理程序获取)。
我不介意使用Twisted代码进行更多帮助,但很可能它已经正确编写了。至少,我建议不要立即尝试制作Twisted flush网络写缓冲区。虽然它可能有助于使您的代码看起来正常工作,但它实际上只是隐藏了稍后会出现的问题。
答案 1 :(得分:1)
您的问题似乎是Twisted缓冲您写入的数据。
显然,没有简单的方法可以强制数据自行发送而无需重构大量代码。请参阅Twisted transport.write和Using 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应用程序以接受在单个消息中包含多个写入时发送的消息类型可能(并且更容易)。