Одностороннее закрытие(half-close) обеспечивает возможность одной стороне закрыть соединение с сокетом, прекратив отправку своих данных, но при этом получая данные с другой стороны.
Вот типичная ситуация. Предположим, что вы отправляете данные на сервер, но не знаете, какой объем данных необходимо передать. Если вы имеете дело с файлом, то, закрыв его, вы тем самым определяете конец данных. Закрыв же сокет, вы немедленно разорвете соединение с сервером.Данную проблему решает одностороннее закрытие. Если вы закроете выходной поток, связанный с сокетом, вы тем самым укажете серверу на окончание запроса. При этом входной поток останется открытым, и вы сможете прочитать ответ.
Программа на стороне клиента, реализующая данный подход, выглядит приблизительно так, как показано ниже.
1 2 3 4 5 6 7 8 9 10 11 12 |
Socket socket = new Socket(host, port); Scanner in = new Scanner(socket.getInputStream()); PrintWriter writer = new PrintWriter(socket.getOutputStream()); // Передача данных запроса. writer.print(...); writer.flush(); socket.shutdownOutput(); // Теперь один из потоков, связанных с сокетом, закрыт. // Чтение ответа. while(in.hasNextLine() != null) {String line = in.nextLine(); . . . } socket.close(); |
Программа на стороне сервера лишь читает данные из входного потока до тех пор, пока не закроется выходной поток на другом конце соединения.
Очевидно, что данный подход применим только при работе с протоколами, подобными HTTP, где клиент устанавливает соединение с сервером, передает запрос, получает ответ, после чего соединение разрывается.