【发布时间】:2012-06-27 04:17:28
【问题描述】:
我在 Android (2.3.x) 上使用 DefaultHttpClient 和 ThreadSafeClientConnManager 将 HTTP 请求发送到我的 REST 服务器(嵌入式 Jetty)。
大约 200 秒的空闲时间后,服务器使用 [FIN] 关闭 TCP 连接。 Android 客户端以 [ACK] 响应。这应该并且确实使套接字处于半关闭状态(服务器仍在侦听,但无法发送数据)。
我希望当客户端再次尝试使用该连接时(通过HttpClient.execute),DefaultHttpClient 将检测到半关闭状态,关闭客户端的套接字(因此发送它是 [FIN/ACK]完成关闭),并为请求打开一个新连接。但是,问题来了。
相反,它通过半关闭的套接字发送新的 HTTP 请求。只有在发送之后才检测到半关闭状态并且在客户端关闭套接字(将[FIN]发送到服务器)。当然,服务器无法响应请求(它已经发送了[FIN]),因此客户端认为请求失败并通过新的套接字/连接自动重试。
最终结果是服务器看到并处理了请求的两个副本。
关于如何解决这个问题的任何想法? (我的服务器对第二个副本做了正确的事情,但我很生气有效载荷被传输了两次。)
DefaultHttpClient 不应该在第一次尝试写入新的 HTTP 数据包时检测到套接字已关闭,立即关闭该套接字并启动一个新的套接字?我对在服务器发送 [FIN] 几分钟后如何在套接字上发送新的 HTTP 请求感到困惑。
【问题讨论】:
-
AndroidHttpClient执行完全相同的行为(即DefaultHttpClient和ThreadSafeClientConnManager以确保线程安全)...也许您可以尝试使用它?我对套接字连接如何工作的细节了解不多,只是一个建议......
标签: java android tcp apache-httpclient-4.x