java - 创建具有多个客户端的服务器

标签 java

我创建了一个服务器和客户端类。当我运行我的程序时,它执行得很好。我能够在服务器和客户端之间进行通信。现在如何才能使多个客户端同时连接到服务器?我希望能够运行客户端类并让它程序连接到服务器和相同的端口。

This is my Server Class.

    import java.io.*;
    import java.net.*;
    import java.awt.event.*;
    import java.awt.*;
    import javax.swing.*;


    public class Server extends JFrame {

     private JTextField enterField;
     private JTextArea displayArea;
     private ObjectOutputStream output;
     private ObjectInputStream input;
     private ServerSocket server;
     private Socket connection;
     private int counter = 1;

       public Server() {
          super("Host Server");

          enterField = new JTextField();
          enterField.setEditable(false);
          enterField.addActionListener(
               new ActionListener() {
                   public void actionPerformed(ActionEvent event) {
                    sendData(event.getActionCommand());
                    enterField.setText("");
                }
            }
        );

    add(enterField, BorderLayout.NORTH);

    displayArea = new JTextArea();
    add(new JScrollPane(displayArea));

     setSize(800,800);
     setVisible(true);
    }

    public void runServer() {
      try {
     server = new ServerSocket(12345, 100);

        while(true) {
            try {
                waitForConnection();
                getStreams();
                processConnection();
            }
            catch (EOFException eofException) {
                displayMessage("\nChat room has close down. Connection Terminated.");
            }
            finally {
                closeConnection();
                ++counter;
            }
        }
    }
    catch (IOException ioException) {
        ioException.printStackTrace();
        }
    }

    private void waitForConnection() throws IOException {
        displayMessage("Waiting for Connection");
        connection = server.accept();
        displayMessage("Connection " + counter + "recieved from: " + 
        connection.getInetAddress().getHostName());
    }

        private void getStreams() throws IOException {
            output = new ObjectOutputStream(connection.getOutputStream());
            output.flush();

            input = new ObjectInputStream(connection.getInputStream());

            displayMessage("\nGot I/O streams\n");
     }

    private void processConnection() throws IOException{
        String message = "Welcome. Chat room has started. \nConnection Successful\n";
        sendData(message);

        setTextFieldEditable(true);

        do {
            try {
                message = (String) input.readObject();
                displayMessage("\n" + message);
            }
            catch (ClassNotFoundException classNotFoundException) {
                displayMessage("\nUnknown object type recieved");
            }
        }while(!message.equals("Client>>>EEEE"));
    }

    private void closeConnection() {
        displayMessage("\nTerminating connection");
        setTextFieldEditable(false);

        try {
            output.close();
            input.close();
            connection.close();
        }
        catch (IOException ioException) {
            ioException.printStackTrace();
        }
    }

    private void sendData(String message) {
        try {
            output.writeObject("Server>>>" + message);
            output.flush();
            displayMessage("\nServer>>> " + message);
        }
        catch (IOException ioException) {
            displayArea.append("\nError writing object");
        }
    }

    private void displayMessage(final String messageToDisplay) {
        SwingUtilities.invokeLater(
                new Runnable() {
                    public void run() {
                        displayArea.append(messageToDisplay);
                    }
                }
        );
    }

    private void setTextFieldEditable(final boolean editable) {
        SwingUtilities.invokeLater(
                new Runnable() {
                    public void run() {
                        enterField.setEditable(editable);
                    }
                }
        );
     }
    public static void main(String[] args) {
        Server application = new Server();
        application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        application.runServer();
    }


}

...

这是我的客户端类。

   import java.io.*;
   import javax.swing.*;
   import java.awt.event.*;
   import java.net.*;
   import java.awt.*;
      public class Client extends JFrame{
         private JTextField enterField;
         private JTextArea displayArea;
         private ObjectOutputStream output;
         private ObjectInputStream input;
         private String message = "";
         private String chatServer;
         private Socket client;

     public Client(String host) {
        super("Client");

        chatServer = host;

        enterField = new JTextField();
        enterField.setEditable(false);
        enterField.addActionListener(
                new ActionListener() {
                    public void actionPerformed(ActionEvent event) {
                        sendData(event.getActionCommand());
                        enterField.setText("");
                     }
                }
            );
        add(enterField, BorderLayout.NORTH);

        displayArea = new JTextArea();
        add(new JScrollPane(displayArea), BorderLayout.CENTER);

        setSize(800,800);
        setVisible(true);
    }

    public void runClient() {

        try {
            connectToServer();
            getStreams();
            processConnection();
        }
        catch (EOFException iofException) {
            displayMessage("\nClient terminated connection");
        }
        catch (IOException ioException) {
            ioException.printStackTrace();
        }
        finally {
            closeConnection();
        }
    }

    private void connectToServer() throws IOException {

        displayMessage("Attempting connection\n");

        client = new Socket(InetAddress.getByName(chatServer), 12345);

        displayMessage("Connected to: " + client.getInetAddress().getHostName());
    }

    private void getStreams() throws IOException {

        output = new ObjectOutputStream(client.getOutputStream());
        output.flush();

        input = new ObjectInputStream(client.getInputStream());


    }

    private void processConnection() throws IOException {

        setTextFieldEditable(true);

        do {
            try {
                message = (String) input.readObject();
                displayMessage("\n" + message);
            }
            catch (ClassNotFoundException classNotFoundException) {
                displayMessage("\nErro with recieving chat message");
            }
        } while (!message.equals("SERVER>>>TERMINATE"));
    }

    private void closeConnection() {
         displayMessage("\nClosing connection");
         displayMessage("\nAll users have left the chat");

         setTextFieldEditable(false);

        try {
            output.close();
            input.close();
            client.close();
        }
        catch (IOException ioException) {
            ioException.printStackTrace();
        }
    }

    private void sendData(String message) {
        try {
            output.writeObject("CLIENT>>> " + message);
            output.flush();
            displayMessage("\nCLIENT>>> " + message);
        }
        catch (IOException ioException) {
            displayArea.append("\nError writing object");
       }
    } 

   `private void displayMessage(final String messageToDisplay) {
        SwingUtilities.invokeLater(
               new Runnable() {
                    public void run() {
                        displayArea.append(messageToDisplay);
                    }
                }
            );
    }

    private void setTextFieldEditable(final boolean editable) {
        SwingUtilities.invokeLater(
                new Runnable() {
                    public void run() {
                        enterField.setEditable(editable);
                    }
                }
            );
    }

    public static void main(String[] args) {
        Client application;

        if(args.length == 0)
            application = new Client("127.0.0.1");
        else
            application = new Client(args[0]);

        application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        application.runClient();
    }
}

...

最佳答案

您当前的服务器实现仅处理来自客户端的一个连接。

要处理多个连接,您需要实现一些 ClientHandler 类,负责读取和写入客户端的套接字,该套接字应在其自己的线程中运行:

class ConnectionHandler implements Runnable {
    private final Socket socket;
    private final Server server;

    public ConnectionHandler(Socket socket, Server server) {
        this.socket = socket;
        this.server = server;
    }

    @Override
    public void run() {
        // implement I/O with client, if client logs out or connection lost, you notify server
    }
}

那么你需要修改你的Server代码以支持多个客户端,例如:

    List<ConnectionHandler> clients = new ArrayList<>();

    private void waitForConnection() throws IOException {
        displayMessage("Waiting for Connection");
        Socket socket = server.accept();
        ConnectionHandler clientHandler = new ConnectionHandler(socket, this);
        clients.add(clientHandler);
        Thread handlerThread = new Thread(clientHandler);
        handlerThread.start();

        displayMessage("Connection #" + clients.size() + "received from: " + 
        socket.getInetAddress().getHostName());
    }

关于java - 创建具有多个客户端的服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61508559/

相关文章:

java - 如何访问输出阶段的 Mapper/Reducer 计数器?

java - 在 Java 中将 Map 中的 Map 转换为 JSON 的问题

java - Spring中的全局资源对象

java - 从不同的类写入 jTextArea

java - 无法让教程应用程序运行 - Android

java - 布局和 Activity 有什么区别?

java - 将文件的字节数组加载到内存中

java - Jersey JAX-RS 客户端 XML 到 java.util.List 反序列化

java - 无法读取 FileWriter 之后生成的 csv 文件并在 Java 中找到重复项

java - MySQL now 方法与时间戳