在下面的代码中我试图使用java applet启动和停止服务器按钮.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();
}
});
答案 0 :(得分:4)
它不会停止,因为您在停止之前创建了一个新实例,并且当您应该在当前{{1}实例上调用requestStop()
时,您甚至不首先启动它}。
TCPServer
答案 1 :(得分:0)
在停止按钮的ActionListener实现中,您正在访问TCPServer的另一个实例(因为您正在创建一个新实例)。所以你设置值"停止"到第二个对象。它对使用开始按钮创建的第一个实例没有影响。
尝试在两个按钮的动作侦听器实现之外实例化TCServer,并为这两个按钮使用该单个实例。
答案 2 :(得分:0)
由于https://docs.oracle.com/javase/7/docs/api/java/net/ServerSocket.html#accept()
ServerSocket::accept
是一种阻止方法,因此只能在成功连接之间检查stop
变量。
您可以使用ServerSocket
(并捕获ServerSocket::setSoTimeout
)或SocketTimeoutException
服务器线程设置interrupt
超时并捕获InterruptedException
。
两个例外都将从ServerSocket::accept
抛出。
请注意,线程中断优先于超时和重复异常捕获。
答案 3 :(得分:0)
试试这个:
public void requestStop() {
stop = true;
interrupt();
}
但是,在这种情况下,我们无法保证,已经处理的逻辑将成功关闭。
此外,您尝试为TCPServer的新实例调用requestStop,而不是已存在。
答案 4 :(得分:0)
您的代码client = serverSocket.accept();
正在阻止。所以一旦你点击了" stopServer"按钮,您请求停止,但只有在客户端向服务器发送下一个请求时才会对其执行操作。你需要做的是在一个单独的线程中运行你的方法run()中的逻辑并捕获InterruptedException和ClosedByInterruptException并清理并返回那里。在你的stopButton上单击,你将在你的线程上调用interrupt()方法。在here