Как аккуратно очистить HTTPURLConnection при обнаружении исключения?

У меня есть Java-апплет, который использует класс HTTPURLConnection для загрузки очень больших файлов в сеть IIS-7. сервер. Апплет разбивает файлы на части, а затем отправляет их POST с использованием потоковой передачи фиксированной длины в сценарий PHP.

Иногда при загрузке фрагментов файлов сетевое соединение между клиентом и сервером таинственным образом разрывается. Когда это происходит, мой вызов метода writeBytes () вызывает исключение IOException , которое я перехватываю. Обнаружив это исключение, я перехожу в свой блок finally , где пытаюсь все исправить. Поскольку в соединение было записано недостаточно данных (помните, что это потоковая передача фиксированной длины), попытка закрыть выходной поток также не удалась . В результате соединение, казалось бы, «застревает» (т. Е. Нижележащий сокет остается открытым). Кажется, это подтверждается просмотром исходного кода метода close () для класса StreamingOutputStream (обратите внимание на комментарий о том, что сокет не может быть закрыт).

Вопрос:

Есть ли удобный способ завершить работу после обнаружения исключения IOException при записи в HTTPURLConnection ? Сообщать объекту HTTPURLConnection disable () недостаточно.

Дополнительная информация:

Вот первое исключение, которое я вижу, когда сеть закрывается из-за моего вызова метода writeBytes () класса HTTPURLConnection :

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)

Я перехватываю это исключение, а затем пытаюсь закрыть объект DataOutputStream , который я использовал для записи в соединение. Когда я это делаю, я получаю следующее исключение:

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)

Я могу проверить, что сокет остается открытым, отметив, что требуется 10 минут, чтобы запись об ошибке появилась в журнале IIS. Эта задержка (10 минут) - это значение тайм-аута моего соединения. Примерные строки из журнала IIS (обрезаны для краткости):

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

Обратите внимание, что в первых двух строках журнала мы аккуратно передаем: 25 МБ отправляется каждый раз, а возвращается код состояния 200. Затем сбой проявляется через 10 минут после последней успешной передачи с бесполезной ошибкой 500 (обратите внимание, что это была только частичная передача; было передано всего ~ 15 МБ). На самом деле это загадочное отключение происходит примерно через 1 минуту после завершения всей процедуры, поэтому сообщения о тайм-ауте, которые я вижу в своих журналах трассировки IIS, являются отвлекающими маневрами. Я не вижу ничего полезного в моих журналах PHP, журнале HTTPERR или в системном журнале на сервере.

6
задан Jonah Bishop 1 February 2012 в 01:22
поделиться