Как с одного модуля закрыть другой?

234
11 апреля 2018, 10:04

Добрый вечер, есть несколько вопросов.

1) Сервер и клиент, если закрывать в следующей последовательности (клиент а после сервер) - все нормально, но если наоборот, клиент звереет и начинает есть ЦП до 100%. Собственно хочу закрыть все клиенты если сервер убит. Или узнать почему они звереют, есть мысль что это из за связи с сервером(сокета после того как клиент соединяется с сервером). Пытался закрыть через сервер, то есть у меня есть массив клиентов, и я хотел пройтись по нему и поотключать их всех. но наткнулся на

Exception in thread "JavaFX Application Thread" java.lang.NullPointerException

И куча всевозможных матов из разных классов по этому пути

at javafx.graphics/com.sun.javafx.text

как я понял он мягко говоря послал меня из за того что я главным потоком сервера лезу в клиент. Идей как можно решить эту проблему уже не осталось, подскажите пожалуйста.

Код связей клиента и сервера ниже.

Сервер

threadListenerNewClient = new Thread(new Runnable() {                                                                                                    
  @Override
        public void run() {
            listenerAllTime();
        }
    });
    threadListenerNewClient.start();
private void listenerAllTime() {
    try (ServerSocket serverSocket = new ServerSocket(9630)){
        while (true){
            new TCPConnection(this, serverSocket.accept());
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
 }

Клиент

try {
tcpConnection = new TCPConnection(this, HOST, PORT);
} catch (IOException e) {
onException(this.tcpConnection, e);}

TCP

public TCPConnection(TCPConnectionListener tCPClient, String ip, int port) throws IOException {
   this(tCPClient, new Socket(ip,port));}
public TCPConnection(TCPConnectionListener tCPClient, Socket socket) throws IOException{
   this.tCPClient = tCPClient;
   this.socket = socket;
   in = new BufferedReader(new InputStreamReader(socket.getInputStream(), Charset.forName("UTF-8")));
   out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),Charset.forName("UTF-8")));
    thread = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                tCPClient.onConnectionReady(TCPConnection.this);
                while (!thread.isInterrupted()) {
                    tCPClient.onReceiveString(TCPConnection.this, in.readLine());
                }
            } catch (IOException e) {
                tCPClient.onException(TCPConnection.this, e);
            } finally {
                tCPClient.onDisconnect(TCPConnection.this);
            }
        }
    });
    thread.start();

2) Сделал jar(ки) сервера и клиента, при закрытии в нормальной последовательности оставались фоновые процессы. Левые потоки тушу так thread.interrupt()(в итоге матов вся консоль) но по идее все работает. И фоновых процессов(от сервера\клиента) не наблюдается. Может есть другие способы закрытия потоков ? ведь есть проекты с использованием множества потоков и закрывать каждый отдельно довольно проблематично. Мне не в лом, но хочу узнать, может есть еще какие-то варианты.

Answer 1

1) NullPointerException в клиенте?
Проверьте, что происходит при вызове onException(this.tcpConnection, e), если tcpConnection=null.

Еще есть небольшое подозрение, что спуталась между собой логика клиента и сервера.
Может стоит вместо одного класса TCPConnection написать два отдельных?

2) Прервать serverSocket.accept() можно из другого потока, вызовом serverSocket.close(). При этом в потоке сервера словите исключение java.net.SocketException.

Также можно перед вызовом accept() установить таймаут setSoTimeout(1000) и проверять какой-нибудь флаг завершения в обработчике исключения java.io.InterruptedIOException.

Сообщения на консоль вы ведь сами и выводите через e.printStackTrace(). Видимо некоторые должны быть обработаны соответсвующим образом, а не просто выведены.

Кстати, чтобы разработка вашего продукта стала легче, стоит сделать два отдельных проекта (чтоб было открыто два отдельных окна Intellij Idea) — один для сервера, а другой для клиента. Так вы сможете запустить одновременно два отладчика.

А еще часто пишут, что после отладки работы с java.net, возможно, придется все переписать на NIO или Netty...

READ ALSO
Android JavaMail Smtp блокировка подозрительных действий

Android JavaMail Smtp блокировка подозрительных действий

Я использую в своем приложении библиотеку для отправки электронных писем JavaMailВсё работает отлично, но при при отправке писем с других городов...

166
Callback на подключение любого bluetooth девайса

Callback на подключение любого bluetooth девайса

Как я могу в активити повесить callback на подключение любого девайса? Те

198
Как конвертировать Long EpochDays в LocalDate?

Как конвертировать Long EpochDays в LocalDate?

Для расчётов мне требовалось перевести LocalDate в epochDays, теперь надо обратноПока сделал вот такую конструкцию:

192