2

我以以下方式编写对 HTTP 请求的响应: response.getOutputStream().write()

我想确保客户收到它。

它必须是可能的,因为 TCP 发送确认。

这个要求也意味着写必须是一个阻塞操作(这对我来说很好!)。

那么我怎么知道它是否以上述方式完成(我怀疑不是)?有什么规范可以保证吗?有什么办法可以做到这一点?我用的是Tomcat 6。

... PS,我的意思是除了让客户端在另一个 HTTP 请求中发送此确认之外的任何方式:)

4

3 回答 3

0

首先,您可以确保刷新输出流缓冲区:

response.getOutputStream().flush();

它保证数据实际发送出去。TCP 将确保它到达,否则会给您的服务器一个错误,该错误将转换为 IOException。

所以简而言之,如果您可以写入并且没有出错,那么您的客户端确实收到了数据。至少在 TCP 堆栈上。客户端显然负责消费消息。

TCP 提供数据完整性和传递保证。它将继续重传,直到接收方确认接收到数据包。但这一切都发生在 TCP 堆栈内部。您的代码可以假设它发生了,或者您收到了错误。只有这两种情况是可能的。

此外,您可能希望确保关闭输出流,否则您的客户端可能会坐在那里缓冲数据,直到它接收到流的结尾。

我希望这有帮助

于 2012-08-06T02:29:14.163 回答
-1

TCP 只知道数据已经被对端接收。它不知道对等应用程序已收到数据。并且 TCP 写入是异步的,因此在写入或刷新返回到发送应用程序之后很长时间才能检测到错误。

应用程序可以通过另一个 HTTP 事务确认收到,但 HTTP 应该是无状态的,这样做会违反该规则。

我建议你查一下“两军问题”。

相反,您应该做的是使您的事务具有幂等性(查找)然后客户有责任确保事务发生。如果客户没有得到响应,他应该只是重复交易。对重试次数设置一个下限,比如两次或三次。

于 2012-08-06T02:53:48.293 回答
-1

你确定那是你想要的吗?测试写入是否成功?TCP 旨在确保其正常工作,如果数据包失败,您将开始断开连接和 IOExeceptions。事实上,你会得到 RunTimeException。这样做的方法是将响应发送回源。并等到响应到来。

等的时候,保证等了一定时间就放弃了,这样才不会挂。

假设您只想调试代码。如果你想调试使用像 ethereal 这样的数据包嗅探器。相信我,一旦你的逻辑正确,你就不需要 ack 数据包。

于 2012-08-06T03:07:20.820 回答