简体   繁体   English

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

[英]Creating a Server with multiple Clients

I created a Server and Client class.我创建了一个服务器和客户端 class。 When I run my program it executes perfectly.当我运行我的程序时,它会完美执行。 I am able to communicate between both Server and Client.我能够在服务器和客户端之间进行通信。 Now how do I make it to where multiple Clients can be connected to the Server at once?现在,我如何才能将多个客户端一次连接到服务器? I want to be able to run the Client class and have it program connect to the Server and same port.我希望能够运行客户端 class 并让它程序连接到服务器和相同的端口。

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


}

... ...

This is my Client Class.这是我的客户 Class。

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

... ...

Your current implementation of Server handles only one connection from client.您当前的服务器实现仅处理来自客户端的一个连接。

To handle multiple connections, you need to implement some ClientHandler class responsible for reading from and writing to the client's socket which should run in its own thread:要处理多个连接,您需要实现一些ClientHandler class 负责读取和写入应该在自己的线程中运行的客户端套接字:

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
    }
}

Then you need to modify your Server code to support multiple clients, for example:然后您需要修改您的服务器代码以支持多个客户端,例如:

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

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

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