Как заставить объект InputStream Java Socket генерировать исключение IOException? - PullRequest
1 голос
/ 17 июня 2020

Я тестирую сетевой компонент, созданный мной поверх java.net.Socket. У меня есть такой код:

try {
   byte[] buffer = new byte[1024]
   int bytesRead = socket.getInputStream().read(buffer);
   // more processing
} catch (IOException e) {
   handleException(e);
}

Как я могу заставить мой InputStream#read вызов выдать IOException, чтобы я мог протестировать метод handleException? Я не хочу издеваться. Я хочу использовать реальную реализацию и хочу использовать только Java API.

1 Ответ

1 голос
/ 17 июня 2020

TLDR

Со стороны записи используйте аварийное закрытие:

socket.setSoLinger(true, 0);
socket.close();

Это приведет к тому, что любые последующие чтения с другой стороны будут выдавать IOException

Подробнее см. Oracle документация :

Во-первых, нам нужно различать guish различия между неудачным и упорядоченное освобождение соединения. Чтобы понять это различие, нам нужно посмотреть, что происходит на уровне протокола TCP. Полезно представить установленное TCP-соединение как два отдельных полунезависимых потока данных. Если двумя одноранговыми узлами являются A и B, то один поток доставляет данные от A к B, а другой поток от B к A. Упорядоченное высвобождение происходит в два этапа. Сначала одна сторона (скажем, A) решает прекратить отправку данных и отправляет сообщение FIN в B. Когда стек TCP на стороне B получает FIN, он знает, что данные больше не поступают от A, и всякий раз, когда B считывает все предыдущие данные с сокет, дальнейшее чтение вернет значение -1, чтобы указать конец файла. Эта процедура известна как полузакрытие TCP, потому что закрывается только половина соединения. Неудивительно, что процедура для второй половины точно такая же. B отправляет сообщение FIN к A, который в конечном итоге получает -1 после прочтения всех предшествующих данных, отправленных A из сокета.

Напротив, при неудачном закрытии используется сообщение RST (Reset). Если одна из сторон выдает RST, это означает, что все соединение прерывается, и стек TCP может отбросить любые данные в очереди, которые не были отправлены или получены ни одним из приложений.

Итак, как работают приложения Java упорядоченные и неудачные релизы? Давайте сначала рассмотрим неудачные релизы. Со времен первоначальных сокетов BSD существовало соглашение о том, что параметр сокета «linger» может использоваться для принудительного прерывания соединения. Любое приложение может вызвать Socket.setLinger (true, 0), чтобы сообщить стеку TCP, что, когда этот сокет закрыт, должна использоваться процедура прерывания (RST). Установка параметра linger не дает немедленного эффекта, за исключением того, что при последующем вызове Socket.close () соединение прерывается с сообщением RST. Как мы вскоре увидим, существуют и другие способы прерывания соединения, но это самый простой способ сделать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...