I have a Java applet that uses the HTTPURLConnection
class to upload very large files to the IIS-7 web server. The applet splits the files into pieces, then the POST files processes flows with a fixed length up to the PHP script.
Sometimes, when downloading fragments of files, the network connection between the client and server mysteriously drops. When this happens, my call to the writeBytes()
method raises an IOException
, which I will catch. After detecting this exception, I drop into the finally
block, where I try to clear things up. Since not enough data was written to the connection (remember that this is a fixed-length streaming), the attempt to close the output stream also stops . As a result, the connection seems to βstickβ (i.e., the underlying socket remains open). This seems to be checked by looking at the source code for the close()
method for the StreamingOutputStream class (note the comment, which states that the socket cannot be closed).
Question:
Is there an elegant way that I can turn off after catching an IOException
when writing to an HTTPURLConnection
? Assigning an HTTPURLConnection
disconnect()
object seems inadequate.
Additional Information:
Here the first exception that I see when the network gets hosed throws my call to the writeBytes()
method of the writeBytes()
class:
java.io.IOException: Error writing request body to server at sun.net.www.protocol.http.HttpURLConnection$StreamingOutputStream.checkError(Unknown Source) at sun.net.www.protocol.http.HttpURLConnection$StreamingOutputStream.write(Unknown Source) at java.io.DataOutputStream.write(Unknown Source) at MultiPartPostThread.run(MultiPartPostThread.java:321)
I will catch this exception and then try to close the DataOutputStream
object that I used to write to the connection. When I do this, I get this exception:
java.io.IOException: insufficient data written at sun.net.www.protocol.http.HttpURLConnection$StreamingOutputStream.close(Unknown Source) at java.io.FilterOutputStream.close(Unknown Source) at MultiPartPostThread.run(MultiPartPostThread.java:370)
I can verify that the socket remains open, noting that it takes 10 minutes to write the failure in the IIS log. This delay (10 minutes) is my connection timeout value. Example lines from the IIS log (abbreviated for brevity):
2012-01-31 20:20:07 POST /upload_handler.php 200 0 0 356 26215490 3666 2012-01-31 20:20:10 POST /upload_handler.php 200 0 0 356 26215490 3853 2012-01-31 20:30:22 POST /upload_handler.php 500 0 64 0 15286099 611442
Please note that in the first two lines of the log we transfer well: 25 MB is sent every time and a status code of 200 is returned. After that, the failure appears 10 minutes after the last successful transfer with a useless error of 500 (and note that this was only partial transfer, only ~ 15 MB transferred). In fact, this mysterious shutdown occurs for about 1 minute throughout the procedure, so the timeout messages that I see in the IIS trace logs are red herrings. I don't see anything useful in my PHP logs, the HTTPERR log, or in the syslog on the server.