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

时间:2014-12-12 19:36:11

标签: 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);
    }
}

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(删除静态引用):

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

我确定它是一个简单的修复程序,但我无法让它终止服务器。我尝试了不同的方法和一切。我知道,如果我只是按下按钮上的Server.Start();,它将使用当前线程启动服务器,这不是我想要的。

它会开始,但我不确定它是否会停止。

3 个答案:

答案 0 :(得分:3)

您正在UI线程上启动服务器......不是一个好主意。要修复,您需要创建另一个线程

实现Runnable或覆盖Thread.run()

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

答案 1 :(得分:0)

在你的DoSomething方法(应该大写为doSomething)中,你总是在创建一个新的服务器,而你没有保留对它的引用。

因此,每次单击该按钮,都会启动一个新服务器。

您需要保留对服务器的引用,并且只有在引用为null时才启动新引用。与Thread相同的问题。

我也不会在服务器静态中使用isRunning方法。

答案 2 :(得分:0)

您可以使用MouseListener,因为您的课程扩展了JFrame。 MouseListener有5种方法可供选择。 mousePressed,mouseClicked,mouseReleased,mouseEntered和mouseExited。

除了mousePressed和mouseClicked(排序)之外,其中每个人都用他们的名字解释自己。

只要单击鼠标上的 ANY 按钮,就会调用mousePressed。当 LEFT CLICK 正在收听的组件(在您的情况下为JFrame)时,会调用mouseClicked。