简体   繁体   中英

make sure `response.getOutputStream().write()` was received

I write a response to an HTTP request in the following manner: response.getOutputStream().write()

I want to make sure the client received it.

It must be possible, as TCP sends acknowledgements.

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.

... PS, I mean any way besides making the client send this acknowledgement in another HTTP request :)

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.

So in short, if you can write and not get an error, your client did receive the data. At least on the TCP stack. The client is obviously responsible for consuming the message.

TCP provides both data integrity and delivery guarantee. It will keep retransmitting until the receiver acknowledges the reception of the packet. But all this happens inside the TCP stack. 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. 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.

The application could acknowledge receipt via another HTTP transaction but HTTP is supposed to be stateless and doing so would violate that rule.

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. Infact you will get 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. Trust me, once you get your logic right, you wont need the ack packet.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM