Я не смог найти удовлетворительный ответ на этот вопрос в любом месте. Объясните это кому-нибудь с пониманием внутренних дел?Первая запись в удаленно закрытый разъем не вызывает исключение, не так ли? Java
Я написал простой клиент/сервер, чтобы продемонстрировать эту проблему. Сервер считывает одну строку текста, затем закрывает сокет. Клиент пишет одну строку текста, ждет 10 секунд, затем записывает еще две строки текста. Вторая запись (через 10 секунд) терпит неудачу, но первая запись всегда преуспевает.
Почему BufferedWriter не генерирует исключение при первой записи? Ведь розетка обычно закрывалась долго. Код также считывает сокет прямо перед первой записью, возвращает -1, чтобы показать, что входная сторона уже обнаружила, что сокет закрыт. Почему выходная сторона также не может это знать?
public class Server {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(9000);
Socket s = ss.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
System.out.println(in.readLine());
s.close();
System.out.println("Socket closed");
}
}
public class Client {
public static void main(String[] args) throws IOException, InterruptedException {
Socket s = new Socket("localhost", 9000);
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
out.write("Hello, World!\n"); out.flush();
Thread.sleep(10000);
System.out.println("Read from socket returns: " + s.getInputStream().read());
out.write("First write\n"); out.flush();
System.out.println("First write succeeded without detecting socket closed");
out.write("Second write\n"); out.flush();
System.out.println("Second write succeeded without detecting socket closed");
}
}
Просто потому, что сокет был закрыт программой, это не значит, что он был закрыт ОС. Пока клиент не получит ответ от базовых систем, что порт ушел, он предполагает, что все хорошо. Вот почему у нас есть протоколы и таймауты. – KevinDTimm
Вы правы, я сменил ожидание на 5 минут, и первая запись вызывает исключение. Таким образом, это, вероятно, какой-то тайм-аут, несмотря на нормальную близкую последовательность; должно быть способом, которым ОС управляет сокетами. –
На самом деле это отвечает на мой вопрос: http://stackoverflow.com/questions/2165670/is-it-possible-to-close-java-sockets-on-both-client-and-server-sides?rq=1 –