简体   繁体   English

在Java中单击按钮时启动和停止服务器

[英]Start and stop a Server upon button click in Java

I have a server class that runs and stops a server for my android app to connect to. 我有一个服务器类,运行和停止服务器为我的Android应用程序连接。 It works fine when just using is from the terminal. 当从终端使用时,它工作正常。 But I want to make it a GUI so i don't have to launch it from anything else. 但我想让它成为一个GUI,所以我不必从其他任何东西启动它。 And to keep a better output on it. 并保持更好的输出。

Heres my Main.java: 继承人我的Main.java:

public class Main {
    public static void main(String[] args) throws Exception {
        Form f = new Form();
        f.setVisible(true);
    }
}

Form.java UPDATED: 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 UPDATED (Removed static references): Server.java UPDATED(删除静态引用):

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();
        }
    }
}

Im sure its a simple fix, but I just can't get it to terminate the server. 我确定它是一个简单的修复程序,但我无法让它终止服务器。 I tried different methods and everything. 我尝试了不同的方法和一切。 I know that if I just call Server.Start(); 我知道如果我只是调用Server.Start(); on the button press that it will use the current thread to start the server, and thats not what I want. 按下按钮,它将使用当前线程启动服务器,这不是我想要的。

It will start, but Im not sure if it ever stops or not. 它会开始,但我不确定它是否会停止。

You are starting your server on the UI thread... Not a great idea. 您正在UI线程上启动您的服务器...不是一个好主意。 To fix, you need to create another Thread 要修复,您需要创建另一个Thread

Either implement a Runnable or override Thread.run() 实现Runnable或覆盖Thread.run()

Runnable r = new Runnable () {
  public void run() {
    Server.Start();
  }
}
new Thread(r).start();

In your DoSomething method (which should be capitalized as doSomething), you are always creating a new Server, and you are not keeping a reference to it. 在您的DoSomething方法(应该大写为doSomething)中,您总是创建一个新的服务器,并且您没有保留对它的引用。

So, every time the button is clicked, you start a new server. 因此,每次单击该按钮,您都会启动一个新服务器。

You'll need to keep a reference to the server, and only start a new one if the reference is null. 您需要保留对服务器的引用,并且只有在引用为null时才启动新引用。 Same problem with the Thread. 与Thread相同的问题。

I wouldn't make the isRunning method in Server static, either. 我也不会在Server静态中创建isRunning方法。

You could use a MouseListener since your class there extends JFrame. 您可以使用MouseListener因为您的类扩展了JFrame。 MouseListener has 5 methods that go along with it. MouseListener有5个方法。 mousePressed, mouseClicked, mouseReleased, mouseEntered, and mouseExited. mousePressed,mouseClicked,mouseReleased,mouseEntered和mouseExited。

Every one of those explains themselves with their name, except for mousePressed and mouseClicked (sort of). 除了mousePressed和mouseClicked(排序)之外,每个人都用他们的名字解释自己。

mousePressed is invoked whenever ANY button on the mouse is clicked. 只要单击鼠标上的任何按钮,就会调用mousePressed。 mouseClicked is invoked when you LEFT CLICK the component (in your case the JFrame ) that is being listened to. 当您左键单击正在收听的组件(在您的情况下为JFrame )时,将调用mouseClicked。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM