Проверьте, не работает ли сервер UDP и DatagramChannel java - PullRequest
0 голосов
/ 29 мая 2020

Итак, я разрабатываю многопоточную систему, которая отправляет команды (шаблон разработки команд) от клиента к серверу, и там они выполняются, а ответ отправляется обратно.

Клиент использует java.nio.channels.DatagramChannel для отправки и получения с использованием UDP.

В основном потоке у меня есть время (true), которое читает команды, которые пишет клиент, и отправляет их на сервер, там обрабатываются (запрос базы данных, изменение в файлах, et c), и ответ отправляется обратно, который принимается в потоке, который всегда активен в ожидании ответа.

Система работает безупречно до момента, когда сервер выйдет из строя, так как это UDP, «невозможно» узнать, когда сервер активен, готов, работает и т.д. c. Итак, я пытаюсь узнать, не работает ли он, заключается в том, что если через одну секунду отправленного запроса нет ответа, клиентская часть переходит к бесконечному l oop, который `` пытается '' подключиться каждые 2 секунды, отправляя команду 'подключиться', пока он не получит положительный ответ.

Поскольку мне нужно использовать поток-получатель отдельно от основного потока, я не могу вычислить ровно через одну секунду после отправки запроса, потому что он работает отдельно, возможно, есть это способ заставить главный поток отвечать, если это больше одной секунды, поэтому он должен повторить попытку подключения, как я сказал ранее. Я читал, что в Thread есть несколько wait() notify() методов, которые, возможно, могут мне помочь, но я не уверен, как я могу их использовать в моем случае. Вниз - это код.

ClientMain. java

while(true) {
    if (channel.isConnected())
        reader.startInteraction(currentUser.getCredentials());
    else
        channel.tryToConnect(address);

    responseHandler.checkForResponse();
}

ClientResponseHandler. java, этот класс имеет поток-получатель как внутренний класс

public void checkForResponse() {
        startRequestTime = System.currentTimeMillis();

        Object received = receiverThread.receivedObject;

        if (received instanceof String && received.equals("connect")) {
            channel.setConnected(true);
            System.out.println("Successfully connected to the server");
        }

        synchronized (this) {
            if (received != null) {
                flagReceived = true;
                printResponse(received);
            } else {
                flagReceived = false;
            }
            receiverThread.receivedObject = null;
        }
    }

Внутри ReceiverThread. java, receivedObject - это изменчивый объект внутри класса Thread

...
protected volatile Object receivedObject = null;
...

public void run() {
    while(true)
        receiveData();
}

public void receiveData() throws IOException, ClassNotFoundException {
            synchronized (ClientResponseHandler.class) {
                //[MARKET]condition that doesn't work protertly
                if (channel.requestWasSent() && !flagReceived && System.currentTimeMillis() - startRequestTime > 1000) {
                    channel.setConnectionToFalse();
                }
            }

            final ByteBuffer buf = ByteBuffer.allocate(AbsUdpSocket.DATA_SIZE);
            final SocketAddress addressFromServer = channel.receiveDatagram(buf);
            buf.flip();

            byte[] bytes = new byte[buf.remaining()];
            buf.get(bytes);

            if (bytes.length < 1)
                return;

            synchronized (ClientResponseHandler.class) {
                channel.setRequestSent(false);
                if (bytes.length < AbsUdpSocket.DATA_SIZE)
                    receivedObject = processResponse(bytes);
                else
                    throw new EOFException();
            }
        }

//The processResponse() is just to convert the received bytes to the needed object

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

...