gpt4 book ai didi

java - 为什么 DefaultHttpClient 通过半关闭套接字发送数据?

转载 作者:可可西里 更新时间:2023-11-01 02:30:41 33 4
gpt4 key购买 nike

我在 Android (2.3.x) 上使用 DefaultHttpClientThreadSafeClientConnManager 将 HTTP 请求发送到我的 REST 服务器(嵌入式 Jetty)。

在约 200 秒的空闲时间后,服务器使用 [FIN] 关闭 TCP 连接。 Android 客户端以 [ACK] 响应。这应该并且确实使套接字处于半关闭状态(服务器仍在监听,但无法发送数据)。

我希望当客户端再次尝试使用该连接时(通过 HttpClient.execute),DefaultHttpClient 会检测到半关闭状态,关闭套接字客户端(因此发送它的 [FIN/ACK] 来完成关闭),并为请求打开一个新连接。但是,有问题。

相反,它通过半关闭的套接字发送新的 HTTP 请求。只有在发送后才会检测到半关闭状态并在客户端关闭套接字(将 [FIN] 发送到服务器)。当然,服务器无法响应请求(它已经发送了 [FIN]),因此客户端认为请求失败并通过新的套接字/连接自动重试。

最终结果是服务器看到并处理请求的两个副本。

关于如何解决这个问题的任何想法? (我的服务器对第二个副本做了正确的事情,但我很生气有效载荷被传输了两次。)

DefaultHttpClient 难道不应该在第一次尝试写入新的 HTTP 数据包时检测到套接字已关闭,立即关闭该套接字,然后启动一个新套接字吗?我对服务器发送 [FIN] 几分钟后如何在套接字上发送新的 HTTP 请求感到困惑。

最佳答案

这是 Java 中阻塞 I/O 的一般限制。除了尝试从套接字中读取之外,根本没有办法查明对方端点是否已关闭连接。 Apache HttpClient 通过使用过时的连接检查来解决这个问题,这实际上是一个非常简短的读取操作。但是,检查可以而且经常被禁用。事实上,由于检查引入的额外延迟,通常建议禁用它。我不知道 Android 附带的 HttpClient 版本在这方面的表现如何,但您可以尝试使用适当的配置参数显式启用检查。

此问题的更好解决方案可能是在一段时间不活动后从连接池中驱逐在特定时间段(比如 150 秒)内空闲的连接。

http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d5e652

关于java - 为什么 DefaultHttpClient 通过半关闭套接字发送数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11219325/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com