Как решить "Сброс соединения по пиру: ошибка записи сокета"?
Когда я читаю содержимое файла с сервера, он возвращает следующее сообщение об ошибке:
Caused by: java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(Unknown Source)
at java.net.SocketOutputStream.write(Unknown Source)
at org.apache.coyote.http11.InternalOutputBuffer.realWriteBytes(InternalOutputBuffer.java:215)
at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:462)
at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:366)
at org.apache.coyote.http11.InternalOutputBuffer$OutputStreamOutputBuffer.doWrite(InternalOutputBuffer.java:240)
at org.apache.coyote.http11.filters.ChunkedOutputFilter.doWrite(ChunkedOutputFilter.java:119)
at org.apache.coyote.http11.AbstractOutputBuffer.doWrite(AbstractOutputBuffer.java:192)
at org.apache.coyote.Response.doWrite(Response.java:504)
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:383)
... 28 more
и моя программа сервлетов
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition","attachment;filename="+filename);
FileInputStream in = new FileInputStream(new File(filepath));
ServletOutputStream output=response.getOutputStream();
byte[] outputByte=new byte[4096];
while(in.read(outputByte,0,4096)!=-1){
output.write(outputByte,0,4096);//error indicates in this line
}
in.close();
output.flush();
output.close();
Как решить эту проблему?
5 ответов
У меня такое же исключение, и в моем случае проблема была в процессе пересмотра. Фактически мой клиент закрыл соединение, когда сервер попытался изменить набор шифров. После копания выясняется, что в обновлении 22 jdk 1.6 процесс пересмотра по умолчанию отключен. Если ваши ограничения безопасности могут помочь, попробуйте включить небезопасное пересмотр, установив sun.security.ssl.allowUnsafeRenegotiation
системное свойство для true
, Вот некоторая информация о процессе:
Пересмотр сеанса - это механизм в рамках протокола SSL, который позволяет клиенту или серверу инициировать новое рукопожатие SSL во время продолжающейся связи SSL. Изначально повторное согласование было разработано как механизм повышения безопасности действующего канала SSL путем запуска обновления криптографических ключей, используемых для защиты этого канала. Однако эта мера безопасности не требуется для современных криптографических алгоритмов. Кроме того, повторное согласование может использоваться сервером для запроса сертификата клиента (для выполнения аутентификации клиента), когда клиент пытается получить доступ к определенным защищенным ресурсам на сервере.
Кроме того, есть отличный пост об этой проблеме в деталях и написано (ИМХО) понятным языком.
Сокет был закрыт клиентом (браузером).
Ошибка в вашем коде:
byte[] outputByte=new byte[4096];
while(in.read(outputByte,0,4096)!=-1){
output.write(outputByte,0,4096);
}
Последний прочитанный, затем записанный пакет может иметь длину < 4096, поэтому я предлагаю:
byte[] outputByte=new byte[4096];
int len;
while(( len = in.read(outputByte, 0, 4096 )) > 0 ) {
output.write( outputByte, 0, len );
}
Это не твой вопрос, а мой ответ...;-)
Кажется, что ваша проблема может возникнуть в
while(in.read(outputByte,0,4096)!=-1){
где он может войти в бесконечный цикл, чтобы не сдвигать смещение (которое всегда равно 0 при вызове). Пытаться
while(in.read(outputByte)!=-1){
который по умолчанию попытается прочитать до outputByte.length в byte[]
, Таким образом, вам не нужно беспокоиться о смещении. Смотрите метод чтения FileInputStrem
У меня была такая же проблема с небольшой разницей:
Исключение было поднято в момент промывки
Это другая проблема переполнения стека. Краткое объяснение было неправильной настройкой заголовка ответа:
response.setHeader ("Content-Encoding", "gzip");
несмотря на несжатое содержание данных ответа.
Таким образом, соединение было закрыто браузером.
Правильный способ "решить" это закрыть соединение и забыть о клиенте. Клиент закрыл соединение, пока вы все еще писали ему, поэтому он не хочет вас знать, вот и все, не так ли?