簡體   English   中英

創建具有多個客戶端的服務器

[英]Creating a Server with multiple Clients

我創建了一個服務器和客戶端 class。 當我運行我的程序時,它會完美執行。 我能夠在服務器和客戶端之間進行通信。 現在,我如何才能將多個客戶端一次連接到服務器? 我希望能夠運行客戶端 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();
    }


}

...

這是我的客戶 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();
    }
}

...

您當前的服務器實現僅處理來自客戶端的一個連接。

要處理多個連接,您需要實現一些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
    }
}

然后您需要修改您的服務器代碼以支持多個客戶端,例如:

    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