在Java中单击按钮启动和停止服务器
我有一个服务器类,它运行并停止我的android应用程序要连接的服务器。只要从终端使用,它就可以正常工作。但我想让它成为一个GUI,这样我就不必从其他任何地方启动它。并保持更好的输出 这是我的Main.java:在Java中单击按钮启动和停止服务器,java,multithreading,server,Java,Multithreading,Server,我有一个服务器类,它运行并停止我的android应用程序要连接的服务器。只要从终端使用,它就可以正常工作。但我想让它成为一个GUI,这样我就不必从其他任何地方启动它。并保持更好的输出 这是我的Main.java: public class Main { public static void main(String[] args) throws Exception { Form f = new Form(); f.setVisible(true);
public class Main {
public static void main(String[] args) throws Exception {
Form f = new Form();
f.setVisible(true);
}
}
Form.java已更新:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Form extends JFrame {
private JTextArea outputArea;
private JButton button;
private Server server; // Created a new Server instance
private Thread t; // Created a new Thread instance
public Form() {
initComponents();
server = new Server(); // Initialized server
}
private void initComponents() {
outputArea = new JTextArea();
button = new JButton();
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setTitle("Home Server");
setSize(400, 350);
setResizable(false);
setLocationRelativeTo(null);
button.setText("Start Server");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
DoSomething();
}
});
outputArea.setSize(400, 350);
outputArea.setEditable(false);
Container pane = getContentPane();
GroupLayout gl = new GroupLayout(pane);
pane.setLayout(gl);
gl.setAutoCreateContainerGaps(true);
gl.setHorizontalGroup(gl.createSequentialGroup()
.addComponent(button)
);
gl.setVerticalGroup(gl.createSequentialGroup()
.addComponent(button)
);
pack();
}
private void DoSomething() {
if (!server.isRunning()) {
t = new Thread(server); // Initialized thread.
t.start();
button.setText("Stop Server");
} else {
t.interrupt();
button.setText("Start Server");
}
}
}
已更新Server.java(已删除静态引用):
import java.io.DataInputStream;
导入java.io.DataOutputStream;
导入java.io.IOException;
导入java.net。*;
导入java.util.Enumeration;
公共类服务器实现可运行{
私有静态ServerSocket ServerSocket=null;
私有静态套接字=null;
私有静态DataInputStream DataInputStream=null;
私有静态DataOutputStream DataOutputStream=null;
专用静态int端口=19586;
私有静态布尔运行=false;
公开作废开始(){
试一试{
System.out.println(“启动服务器…”);
serverSocket=新的serverSocket(端口);
System.out.println(“服务器已启动”);
System.out.println(“IP地址:+getIpAddress());
System.out.println(“侦听:+serverSocket.getLocalPort());
运行=真;
}捕获(IOE异常){
e、 printStackTrace();
}
试一试{
System.out.println(“试图连接到客户端…”);
socket=serverSocket.accept();
dataInputStream=新的dataInputStream(socket.getInputStream());
dataOutputStream=新的dataOutputStream(socket.getOutputStream());
System.out.println(“ip:+socket.getInetAddress());
System.out.println(“消息:+dataInputStream.readUTF());
dataOutputStream.writeUTF(“已连接”);
}捕获(例外e){
e、 printStackTrace();
}
}
公共停车场(){
如果(正在运行){
if(套接字!=null){
试一试{
socket.close();
}捕获(IOE异常){
e、 printStackTrace();
}
}
如果(dataInputStream!=null){
试一试{
dataInputStream.close();
}捕获(IOE异常){
e、 printStackTrace();
}
}
如果(dataOutputStream!=null){
试一试{
dataOutputStream.close();
}捕获(IOE异常){
e、 printStackTrace();
}
}
运行=错误;
}
}
私有字符串getIpAddress(){
字符串ip=“”;
试一试{
枚举枚举enumNetworkInterfaces=NetworkInterface.getNetworkInterfaces();
while(enumNetworkInterfaces.hasMoreElements()){
NetworkInterface NetworkInterface=enumNetworkInterfaces.nextElement();
枚举Enumeration enumInetAddress=networkInterface.getInetAddresses();
while(enumInetAddress.hasMoreElements()){
InetAddress InetAddress=enumInetAddress.nextElement();
if(inetAddress.isSiteLocalAddress()){
ip+=“SiteLocalAddress:”+inetAddress.getHostAddress();
}
}
}
}捕获(SocketException e){
e、 printStackTrace();
ip++=“有问题!”+e.toString()+“\n”;
}
返回ip;
}
公共布尔值正在运行(){
返回运行;
}
公开募捐{
而(!Thread.interrupted()){
Start();
}
}
}
我相信这是一个简单的修复,但我只是不能让它终止服务器。我尝试了不同的方法和一切。我知道如果我只调用Server.Start()按下按钮上的code>,它将使用当前线程启动服务器,这不是我想要的
它将启动,但我不确定它是否会停止。您正在UI线程上启动服务器。。。这不是个好主意。要修复此问题,您需要创建另一个线程
实现一个Runnable
或重写Thread.run()
在DoSomething方法(应该大写为DoSomething)中,您总是在创建一个新服务器,并且没有保留对它的引用
因此,每次单击按钮时,您都会启动一个新服务器
您需要保留对服务器的引用,并且仅当引用为null时才启动新的引用。线程也有同样的问题
我也不会使服务器中的isRunning方法是静态的。您可以使用MouseListener
,因为您在那里的类扩展了JFrameMouseListener
有5种方法。鼠标按下、鼠标滑动、鼠标松开、鼠标滑动和鼠标退出
每个人都用自己的名字来解释自己,除了“鼠标按下”和“鼠标滑动”(有点)
只要单击鼠标上的任何按钮,就会调用mousePressed。当您左键单击正在侦听的组件(在您的示例中是JFrame
)时,会调用mouseClicked。这被标记为android,因为…?@njzk2我没有注意到我这样做了。这到底是怎么回事?我对Java非常陌生,在ActionListener/Event HandlerI中执行此操作是为了启动它,我无法终止它,除非我关闭表单。它不会终止,因为启动时您锁定了GUI线程。因此,您需要在一个新线程中启动服务器。我将它放在我的DoSomething()
函数中,我可以打开和关闭它,但现在我在停止时收到一个IOException。它关闭它,但仍然抛出错误。因此,当我停止它时,是否应该将实例设置为server=null?或者设置thread=null
?我可以在新线程上启动服务器,但无法启动
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.*;
import java.util.Enumeration;
public class Server implements Runnable {
private static ServerSocket serverSocket = null;
private static Socket socket = null;
private static DataInputStream dataInputStream = null;
private static DataOutputStream dataOutputStream = null;
private static int port = 19586;
private static boolean running = false;
public void Start() {
try {
System.out.println("Starting Server...");
serverSocket = new ServerSocket(port);
System.out.println("Server Started");
System.out.println("IP Address: " + getIpAddress());
System.out.println("Listening: " + serverSocket.getLocalPort());
running = true;
} catch (IOException e) {
e.printStackTrace();
}
try {
System.out.println("Attempting to connect to clients...");
socket = serverSocket.accept();
dataInputStream = new DataInputStream(socket.getInputStream());
dataOutputStream = new DataOutputStream(socket.getOutputStream());
System.out.println("ip: " + socket.getInetAddress());
System.out.println("message: " + dataInputStream.readUTF());
dataOutputStream.writeUTF("connected");
} catch (Exception e) {
e.printStackTrace();
}
}
public void Stop() {
if (running) {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (dataInputStream != null) {
try {
dataInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (dataOutputStream != null) {
try {
dataOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
running = false;
}
}
private String getIpAddress() {
String ip = "";
try {
Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface.getNetworkInterfaces();
while (enumNetworkInterfaces.hasMoreElements()) {
NetworkInterface networkInterface = enumNetworkInterfaces.nextElement();
Enumeration<InetAddress> enumInetAddress = networkInterface.getInetAddresses();
while (enumInetAddress.hasMoreElements()) {
InetAddress inetAddress = enumInetAddress.nextElement();
if (inetAddress.isSiteLocalAddress()) {
ip += "SiteLocalAddress: " + inetAddress.getHostAddress();
}
}
}
} catch (SocketException e) {
e.printStackTrace();
ip += "Something Wrong! " + e.toString() + "\n";
}
return ip;
}
public boolean isRunning() {
return running;
}
public void run() {
while (!Thread.interrupted()) {
Start();
}
}
}
Runnable r = new Runnable () {
public void run() {
Server.Start();
}
}
new Thread(r).start();