Tomcat - Servlet response blocking - problems with flush

不想你离开。 提交于 2019-12-05 18:22:43

Your server code looks fine. The problem is with your client code. It does not obey the HTTP protocol and is treating the response like a bunch of lines.

Quick fix on the server. Change to:

    sb.append("An additional line to see when it turns up on the client.\n");

Your client is blocking because you are using readLine to read the body of the message. readLine hangs because the body does not end with a line feed. Finally Tomcat times out, closes the connection, your buffered reader detects this and returns the remaining data.

If you make the change above (to the server), This will make your client appear to work as you expect. Even though it is still wrong.

If you want to do your own HTTP parser, you have to read through the headers until you get two blank lines. Then you need to scan the headers to see if you had a Content-Length header. If there is no Content-Length then you are done. If there is a Content-Length you need to parse it for the length, then read exactly that number of additional bytes from the stream. This allows HTTP to transport both text data and also binary data which has no line feeds.

I recommend you replace the guts of your client code HTTP writer/parse with a pre-written client library that handles these details for you.

LOL Ok, I was doing something wrong (by omission). The solution to my issue? Add the following header to my http request,

Connection: close

That simple. Without that, the connection was staying alive. My code was relying on the server signifying that it was finished, but, the server was still listening on the open connection rather than closing it.

The header causes the server to close the connection when it finishes writing the response (which I guess is signified when its call to doPost(...) returns).

Addendum

With regard to the funky characters when flush() is called...

My server code, now that I'm using Connection: close, does not call flush(). However, if the content to be sent back is large enough (larger than the Tomcat connector's buffer size I suspect), I still get the funky characters sent back and the header 'Transfer-Encoding: chunked' appears in the response.

To fix this, I explicitly call, on the server side, response.setContentLength(...) prior to writing my response. When I do this, the Content-Length header is in the response instead of Transfer-Encoding: chunked, and I don't get the funky characters.

I'm not willing to burn any more time on this as my code is now working, but I do wonder if the funky characters were chunk delimiters, where, once I explicitly set the content length, the chunk delimiters were no longer necessary.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!