В следующем коде я пытаюсь запустить и остановить сервер на кнопке с помощью java-апплета. Start хорошо работает с потоком, но я хочу остановить сервер на кнопке. Я использовал переменную volatile , но сервер не останавливается.
Вот код:
public class TCPServer extends Thread {
public static final int SERVERPORT = 8002;
private boolean running = false;
public volatile boolean stop = false;
public Socket client = null;
public static void main(String[] args) {
ServerBoard frame = new ServerBoard();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public void run() {
super.run();
running = true;
try {
System.out.println("Server Has Started........ \n Waiting for client........");
ServerSocket serverSocket = new ServerSocket(SERVERPORT);
try {
while (!stop && running) {
client = serverSocket.accept();
System.out.println("Connection Accepted......");
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
String usercmnd = in.readLine();
if (usercmnd != null) {
Runtime runtime = Runtime.getRuntime();
Process p = runtime.exec(usercmnd);
}
}
if (stop) {
serverSocket.close();
client.close();
System.out.println("Server Has Stopped");
System.exit(0);
}
} catch (Exception e) {
System.out.println("Error");
e.printStackTrace();
}
} catch (Exception e) {
System.out.println("Error");
e.printStackTrace();
}
}
public void requestStop() {
stop = true;
}
}
Но всякий раз, когда я нажимаю кнопку остановки, которая останавливает сервер, он не показывает никаких выходных данных на консоли, как я ожидал по коду. Он также не показывает никаких ошибок, вот код кнопки остановки
stopServer = new JButton("Stop");
stopServer.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
stopServer.setEnabled(false);
startServer.setEnabled(true);
mServer = new TCPServer();
mServer.requestStop();
}
});
5 ответов
Это не останавливается, потому что вы создаете новый экземпляр перед его остановкой, и вы даже не запускаете его сначала, пока вы должны вызвать requestStop()
в текущем экземпляре TCPServer
.
// Here you create a new instance instead of using the existing one
mServer = new TCPServer();
mServer.requestStop();
Из-за https://docs.oracle .com / javase / 7 / docs / api / java / net / ServerSocket.html # accept ().
ServerSocket::accept
- это метод блокировки, поэтому переменную stop
можно проверить только между успешными соединениями.
Вы можете установить тайм-аут ServerSocket
с помощью ServerSocket::setSoTimeout
(и catch SocketTimeoutException
) или interrupt
Server thread and catch InterruptedException
.
Оба исключения будут выброшены из ServerSocket::accept
.
Обратите внимание, что прерывание потока предпочтительнее тайм-аутов и повторного перехвата исключений.
Попробуй это:
public void requestStop() {
stop = true;
interrupt();
}
Однако в этом случае мы не можем гарантировать, что уже обрабатывающая логика будет успешно завершена.
Кроме того, вы пытаетесь вызвать requestStop для нового экземпляра TCPServer вместо уже существующего.
Ваш код client = serverSocket.accept();
блокируется. Итак, как только вы нажали кнопку «stopServer», вы запросили остановку, но она будет выполнена только после того, как клиент отправит следующий запрос на сервер. Что вам нужно сделать, так это запустить вашу логику в вашем методе run () в отдельном потоке и поймать там InterruptedException и ClosedByInterruptException, очистить и вернуться туда. Щелкнув по кнопке stopButton, вы вызовете метод interrupt () в своем потоке. Прочтите об этом здесь
В вашей реализации ActionListener для кнопки остановки вы получаете доступ к другому экземпляру TCPServer (так как вы создаете новый). Итак, вы устанавливаете значение «Стоп» для второго объекта. Это не влияет на первый экземпляр, созданный с помощью кнопки запуска.
Попробуйте создать экземпляр TCServer вне вашей реализации прослушивателя действий для обеих кнопок и используйте этот единственный экземпляр для обеих.
Похожие вопросы
Новые вопросы
java
Java — это высокоуровневый объектно-ориентированный язык программирования. Используйте этот тег, если у вас возникли проблемы с использованием или пониманием самого языка. Этот тег часто используется вместе с другими тегами для библиотек и/или фреймворков, используемых разработчиками Java.