简体   繁体   English

确保已收到`response.getOutputStream()。write()`

[英]make sure `response.getOutputStream().write()` was received

I write a response to an HTTP request in the following manner: response.getOutputStream().write() 我以以下方式编写对HTTP请求的response.getOutputStream().write()response.getOutputStream().write()

I want to make sure the client received it. 我想确保客户收到了它。

It must be possible, as TCP sends acknowledgements. 由于TCP发送确认,因此它必须是可能的。

This requirement also implies that the write MUST be a blocking operation (it's fine by me!). 这个要求还意味着写操作必须是阻塞操作(对我来说很好!)。

So how do I know if it's done the above way (I suspect it's not)? 因此,我如何知道是否以上述方式完成(我怀疑不是这样)? Any specification that guarantees it? 有保证的规格吗? Any way to make that happen? 有什么办法做到这一点? I'm with Tomcat 6. 我在使用Tomcat 6。

... PS, I mean any way besides making the client send this acknowledgement in another HTTP request :) ... PS,我的意思是除了让客户端在另一个HTTP请求中发送此确认之外,还有其他方法:)

First, you can make sure you flush the output stream buffer: 首先,您可以确保刷新输出流缓冲区:

response.getOutputStream().flush();

It guarantees that the data is actually sent out. 它保证了数据实际发送出去。 TCP will make sure that it arrives or else will give your server an error which will translate into an IOException. TCP将确保它到达,否则将给您的服务器一个错误,该错误将转换为IOException。

So in short, if you can write and not get an error, your client did receive the data. 简而言之,如果您可以编写但不会出错,则您的客户端确实收到了数据。 At least on the TCP stack. 至少在TCP堆栈上。 The client is obviously responsible for consuming the message. 客户显然负责消费消息。

TCP provides both data integrity and delivery guarantee. TCP同时提供数据完整性和交付保证。 It will keep retransmitting until the receiver acknowledges the reception of the packet. 它将一直重新传输,直到接收器确认接收到数据包为止。 But all this happens inside the TCP stack. 但是所有这些都发生在TCP堆栈内部。 Your code can just assume it happened or you received an error. 您的代码可以假设它发生了,或者您收到了错误。 Only these two cases are possible. 仅这两种情况是可能的。

Also, you might want to make sure you close the output stream or else your client might be sitting there buffering data until it receives an end of stream. 另外,您可能要确保关闭输出流,否则客户端可能坐在那里缓冲数据,直到它接收到流的结束。

I hope this helps 我希望这有帮助

TCP only knows that the data has been received by the peer. TCP仅知道对等方已接收到数据。 It doesn't know that the peer application has received the data. 它不知道对等应用程序已接收到数据。 And TCP writes are asynchronous, so the error could be detected long after the write or flush has returned to the sending application. 由于TCP写入是异步的,因此可以在写入或刷新返回到发送应用程序后很长时间检测到错误。

The application could acknowledge receipt via another HTTP transaction but HTTP is supposed to be stateless and doing so would violate that rule. 应用程序可以通过另一个HTTP事务确认接收,但是HTTP应该是无状态的,这样做会违反该规则。

I suggest you look up the 'two-army problem'. 我建议您查找“两军问题”。

What you should do instead is make your transactions idempotent (look it up) Then it is the client's responsibility to ensure the transaction occurs. 相反,您应该做的是使交易成为幂等 (查找),然后客户有责任确保交易发生。 If the client does not get the response he should merely repeat the transaction. 如果客户没有得到回应,他应该只重复交易。 Put a low limit on the number of retries, say two or three. 对重试次数设置一个较低的限制,例如两次或三次。

Are you sure that is what you want ? 您确定那是您想要的吗? Test if a write succeeded ? 测试写入是否成功? TCP is designed to ensure that it works, if a packet fails you will start getting disconnections and IOExeceptions. TCP旨在确保其正常工作,如果数据包失败,您将开始断开连接和IOExeceptions。 Infact you will get RunTimeException. 实际上,您将获得RunTimeException。 The way to do this will be to send a response back to the source. 这样做的方法是将响应发送回源。 And wait until the response comes. 然后等待响应出现。

When you wait, ensure that you wait for a certain period of time and give up, so that you dont hang. 当您等待时,请确保您等待了一段时间并放弃,以免您挂死。

Assuming you only want to debug your code. 假设您只想调试代码。 If you are wanting to debug use packet sniffers like ethereal. 如果要调试,请使用诸如ethereal之类的数据包嗅探器。 Trust me, once you get your logic right, you wont need the ack packet. 相信我,一旦您掌握正确的逻辑,就不需要ack数据包了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 最佳做法response.getOutputStream - best practice response.getOutputStream response.getOutputStream已被调用 - response.getOutputStream has already been called 调用response.getOutputStream()之后,Jasper Reports servlet停止工作。 - The Jasper Reports servlet stopped working after calling response.getOutputStream() 我应该通过response.getOutputStream()显式关闭ZipOutputStream吗? - Should I explicitly close ZipOutputStream over response.getOutputStream()? PdfWriter.getInstance(document,response.getOutputStream())的等效项是什么? 脱颖而出 - what is equivalent for PdfWriter.getInstance(document,response.getOutputStream()); to excel 在JSP中将MySQL请求抛出IllegalStateException时使用的response.getOutputStream - response.getOutputStream used on MySQL request throwing IllegalStateException in JSP 第一次调用时response.getOutputStream()抛出IllegalStateException - response.getOutputStream() throws IllegalStateException when called for the first time 如何确保写csv是完整的? - How to make sure that write csv is complete? 如何在 Android Studio 中延迟 getOutputStream().write()? - How to delay getOutputStream().write() in Android Studio? 春季:已经为此响应调用了getOutputStream() - Spring: getOutputStream() has already been called for this response
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM