Я сделал пример моей ситуации:InputStream не обнаруживает, когда в другой СТОРОНЕ OuputStrem и гнездо закрыты
У меня есть клиент продуцирующих Doubles номер (Really мне нужно отправить байты) на другой стороне у меня есть Сервер, присутствующий на запросе клиентов (для этого примера только один), и создает Работника ...
Проблема заключается в том, что рабочий (с InputStream, созданный в соответствии с Socket, принятый сервером) не обнаруживает, когда Клиент (закрывающий OutputStream и Socket) завершается.
Вот мой код:
Client
class ProducerDouble extends Thread {
private Socket consSocket = null;
private OutputStream output = null;
private byte[] innerBytes = null;
private boolean isRunning = false;
public ProducerDouble(String consHost , int consPort) {
try {
consSocket = new Socket(consHost, consPort);
}
catch (UnknownHostException e) {
System.out.println("Unknown host!");
}
catch (IOException e) {
System.out.println("Consumer :"+e.getMessage());
}
try {
if (!(consSocket == null)) {
output = consSocket.getOutputStream();
}
}
catch (IOException e) { }
}
@Override
public void run() {
if (!(consSocket == null)) {
isRunning = true;
int read = 0;
while (isRunning) {
try {
if (!(innerBytes == null)) {
output.write(innerBytes, 0, innerBytes.length);
System.out.println("ProducerDouble "+innerBytes.length +" bytes written");
innerBytes = null;
} else {
try {
Thread.sleep(2000);
String sSending = "The generated double is:"+Double.toString(Math.random()*100.0);
innerBytes = sSending.getBytes();
} catch (InterruptedException ex) { }
}
} catch (IOException e) { }
}
try {
output.close();
} catch (IOException e) { }
try {
consSocket.close();
} catch (IOException e) { }
System.out.println("\n Exiting ProducerDouble...\n");
}
}
public void stopExecute() {
isRunning = false;
}
}
работник
class ConsumerDouble extends Thread {
private Socket clientSocket = null;
private InputStream input = null;
private byte[] innerBytes = null;
private boolean isRunning = false;
public ConsumerDouble(Socket newClientSocket) {
clientSocket = newClientSocket;
try {
input = clientSocket.getInputStream();
} catch (IOException e) { }
}
@Override
public void run() {
isRunning = true;
while (isRunning) {
System.out.println("ConsumerDouble running");
try {
if (innerBytes == null) {
if (input.available() > 0) {
innerBytes = new byte[input.available()];
int read = input.read(innerBytes, 0, innerBytes.length);
System.out.println("ConsumerDouble " + innerBytes.length
+" bytes read from Host ");
} else {
try {
Thread.sleep(1500);
} catch (InterruptedException ex) { }
}
}
} catch (IOException e) {
isRunning = false;
System.out.println("\nConsumerDouble IOException:"+e.getMessage()+"\n");
}
}
System.out.println("\n ConsumerDouble Request Terminated...\n");
try { if (input != null) input.close(); } catch (IOException e) { }
try { if (clientSocket != null) clientSocket.close(); } catch (IOException e) { }
}
public void stopExecute() {
isRunning = false;
}
}
Запуск и остановка сервера
if (jToggleButtonServer.isSelected()) {
thrdSrvrDouble = new Thread() {
@Override
public void run() {
try {
SrvrSocketDouble = new ServerSocket(1023);
System.out.println("ServerDouble Listening on port number: "+1023);
} catch (IOException e) {
System.out.println("Could not listen on port: "+1023);
}
bThrdServerDoubleRunning = true;
while (bThrdServerDoubleRunning) {
Socket clientSocket = null;
try {
clientSocket = SrvrSocketDouble.accept();
System.out.println("New Client Address: " + clientSocket.getInetAddress() + " Port:" + clientSocket.getPort());
} catch (IOException e) {
if(!bThrdServerDoubleRunning) {
System.out.println("ServerDouble Stopped.") ;
break;
}
throw new RuntimeException("Error: ServerDouble accepting client connections", e);
}
if (consumerDouble == null) {
consumerDouble = new ConsumerDouble(clientSocket);
consumerDouble.start();
}
}
consumerDouble.stopExecute();
System.out.println("\n Exiting ServerDouble!!!");
}
};
thrdSrvrDouble.start();
} else {
bThrdServerDoubleRunning = false;
try {
SrvrSocketDouble.close();
} catch (IOException e) { }
}
Переменные
static ServerSocket SrvrSocketDouble;
Thread thrdSrvrDouble = null;
static boolean bThrdServerDoubleRunning = false;
ProducerDouble producerDouble = null;
Запуск и остановка клиента (ProducerDouble)
if (jToggleButtonProducer.isSelected()) {
String sConsHost = jtfSrClConsHost.getText();
producerDouble = new ProducerDouble(sConsHost, 1023);
producerDouble.start();
} else {
producerDouble.stopExecute();
}
В Ouput
run:
ServerDouble Listening on port number: 1023
New Client Address: /192.168.0.16 Port:51056
ConsumerDouble running
ConsumerDouble running
ProducerDouble 41 bytes written
ConsumerDouble running
ConsumerDouble 41 bytes read from Host
ConsumerDouble running
ConsumerDouble running
ConsumerDouble running
ConsumerDouble running
ConsumerDouble running
ConsumerDouble running
ConsumerDouble running
ConsumerDouble running
ProducerDouble 41 bytes written
Exiting ProducerDouble...
ConsumerDouble running
ConsumerDouble running
ConsumerDouble running
ConsumerDouble running
ConsumerDouble running
ConsumerDouble running
ConsumerDouble running
ConsumerDouble running
ConsumerDouble running
ConsumerDouble running
ConsumerDouble running
ConsumerDouble running
ConsumerDouble running
ConsumerDouble running
ConsumerDouble running
ConsumerDouble running
ConsumerDouble running
ConsumerDouble running
ConsumerDouble running
ConsumerDouble running
ConsumerDouble running
ConsumerDouble running
ConsumerDouble running
ConsumerDouble running
ConsumerDouble running
ServerDouble Stopped.
Exiting ServerDouble!!!
ConsumerDouble Request Terminated...
BUILD SUCCESSFUL (total time: 2 minutes 0 seconds)
Когда ProducerDouble заканчивает Exiting ProducerDouble...
, по крайней мере, CustomerDouble должен быть завершен, также распечатывая сообщение ConsumerDouble IOException: (the message Exception)
!
Вопрос
- Что является причиной для исключения не брошено в то время как петля Worker (ConsumerDouble)?
- Как я могу это решить?
PD: Я читал ...
How to detect a remote side socket close? но для меня OutputStream работает определить, когда InputStream закрывается (проблема с InputStream не обнаруживает, когда OutputStream закрыт, даже если сокет создатель выход (с другой стороны) закрыт)!
Socket close vs Inputstream close не имеет отношения к моему вопросу.
Спасибо!
Reading: https://docs.oracle.com/javase/8/docs/api/java/io/InputStream.html#available-- Я ошибся с: Реализация этого метода в подклассе может вызывать исключение IOException, если этот входной поток был закрыт вызовом метода close(). –
Вопрос: что происходит, когда на другой стороне (выходной поток не отправляется, но остается открытым)? Какое значение возвращается 'inputstream (read)' 0 или -1? –
Размер массива байтов для приема байтов из 'inputstread.read (ArrayBytes)' вычисляется (I knpw, который не является точным) в соответствии с методом 'inputstread.available()'. –