2012-10-07 49 views
0

从冰淇淋三明治升级到果冻豆后,客户端(Galaxy Nexus)和自定义服务器之间似乎出现时间问题。这里是一般流程:套接字关闭时间

  1. 客户端打开插座,问题HTTP GET到服务器
  2. 服务器接受,开始新的线程,与HTTP报头和200 OK响应。
  3. 服务器将(二进制)文件写入套接字。
  4. 客户端从套接字读取数据并保存到文件。
  5. 服务器线程后写的所有数据,它关闭套接字,并终止

这比之前的果冻豆更新过去的几个月中运作良好。自更新以来,二进制传输大约70%的时间成功。当'serverSocket.getInputStream()。read'返回一个-1指示已达到流结束时,剩下的30%将失败 。没有数据被读取,未引发错误异常,logcat中没有任何异常。

当我在步骤#5中更改服务器行为时,会出现计时问题的可能性。线程在写完观察到的问题后关闭了套接字。如果我关闭套接字,写完后终止线程,并让操作系统最终关闭套接字,然后它似乎一直工作。

我使用tcpdump和WireShark来查看成功和失败情况下的数据包。在失败的情况下,套接字在几毫秒内关闭,而在成功的情况下,套接字关闭的时间为四分之一秒或更多秒。这是因为我们在套接字关闭时造成的延迟增加了我们成功的机会。

如果任何人有任何建议与我们可能会导致此问题或建议如何缩小问题,请随时作出回应。如果需要,我可以添加代码示例。

+0

请参阅我编辑的答案。 – Luis

回答

-1

看起来,当服务器要求连接关闭时,套接字立即关闭。也许默认的火箭队逗留时间在版本之间改变了?

尝试设置插座盘桓的时间使用:

socket.setSoLinger(boolean on, int timeout); 

让服务器等待一段时间关闭通道之前,如果一些数据仍然等待发送。

如果不能解决,你可以改变你的流量以上:

...

4.Client从插座中读取数据并保存到文件中。

5.客户端向服务器发送确认。

6.服务器关闭连接。

--EDITED-- 一个gracefull方式才达到上述而不考虑关闭确认行驶额外的TCP数据包是:

当服务器完成写入到插座来电:

socket.shutdownOutput(); 

时客户端socket.read()返回-1,客户端调用:

socket.close(); 

这保证了客户被告知所有的数据已经仙t,并且发送者将等待套接字关闭协议完成。

+0

感谢您的回复。我们尝试了没有区别的流连忘返。它确实有助于证明我们的重试代码!添加确认是我们试图避免的。如果我们需要,但现在我们会寻求其他解决方案。 – Dent

+0

你尝试过“socket.setTcpNoDelay()”吗? – Luis

+0

我相信setTcpNoDelay()将不起作用。我们的测试案例很小,并且包含在一个包含PSH的单个TCP数据包中。另外,我们对HTTP get的理解,服务器负责首先关闭连接。虽然不违反提出的解决方案,但不符合标准(?)。仍然试图了解它是否是我们的实现或其他。 – Dent