当前位置: 首页 > 知识库问答 >
问题:

DefaultHttpClient为什么要通过半封闭套接字发送数据?

东郭和光
2023-03-14

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

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

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

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

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

有什么办法解决这个问题吗?(我的服务器用第二个副本做了正确的事情,但是我很恼火有效载荷被传输了两次。)

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

共有1个答案

桑成荫
2023-03-14

这是Java中阻塞I/O的一般限制。除了尝试从套接字读取之外,根本无法确定对面endpoint是否关闭了连接。Apache Http客户端通过使用如此陈旧的连接检查来解决这个问题,这本质上是一个非常简短的读取操作。然而,检查可以而且经常被禁用。事实上,由于检查引入的额外延迟,禁用它通常是明智的。我不知道Android附带的Http客户端版本在这方面的行为如何,但您可以尝试使用适当的配置参数显式启用检查。

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

http://HC . Apache . org/http components-client-ga/tutorial/html/connmgmt . html # d5e 652

 类似资料:
  • 问题内容: 您好,我尝试使用Java中的客户端-服务器类发送文件。由于某种原因,当调用发送文件的方法时,套接字关闭。这是代码: 和来自客户端的代码: 和我得到的错误消息:严重:null java.net.SocketException:套接字已关闭 我对此并没有真正的经验,所以如果有帮助的话会很棒。 问题答案: 该方法返回一个,代表它实际读取的字节数。不能保证从字节数组中读取所需的字节数。它通常会

  • 我正试图通过Java的socket发送一个custome对象。我知道我需要将具有我需要发送的对象的类放在相同的包中,具有相同的serialVersionUID并实现Serializable。我已经这样做了,但我仍然不能通过套接字发送对象。我错在哪里了? 以下是客户端代码: 客户端中的类用户 发送user类对象的代码: 这里是服务器的代码: user类的代码:与客户端的user完全相同(我从客户端复

  • 我试着做一个简单的服务器-客户机套接字通信,但服务器似乎无法正常工作。无论何时发送或接收,我都会收到此错误: 非插座上的插座操作:非插座上的插座操作 奇怪的是,这只会在服务器发送时出现。客户似乎还可以:

  • 问题内容: 我有两个脚本,Server.py和Client.py。我有两个目标: 为了能够一次又一次地从客户端向服务器发送数据。 为了能够将数据从服务器发送到客户端。 这是我的Server.py: 这是我的客户: 该函数首次运行(“ e”进入服务器,我返回返回消息),但是如何使它一遍又一遍地发生(类似于聊天应用程序)?该问题在第一次之后开始。消息不会在第一次之后发送。我究竟做错了什么?我是pyth

  • 我有一个问题,然后通过套接字发送列表,它必须是字节样的对象,好吧,我可以转换它字符串,然后做,但问题是字符串,这是很难重建它 列表从字符串,和从库 没有工作,然后我有这样的东西: 这就是问题所在,我必须拥有这些对象,我的问题是如何发送python对象而不需要将其转换为字符串,或者类似于JSON之类的对象符号? 这可以通过Python套接字文档在基本套接字服务器上进行测试。 失败的文本评估: 错误:

  • 我必须对FTP服务器进行编码,而且我在数据传输方面遇到了问题。 我在linux上使用ftp命令来测试它,我目前正在使用,它发送工作目录中的文件/目录列表。一切正常(ftp打印文件列表),除了ftp打印以下警告: 我想删除该警告,我认为ftp需要二进制数据,但我不知道如何通过套接字发送这样的数据,我目前正在使用最基本的方式发送结果: