java 如何让多个客户端连接到服务器java

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16493222/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 23:07:11  来源:igfitidea点击:

How to have multiple clients connect to a server java

javasocketsclientchatroom

提问by user2371981

I coded a basic isnatnt messager program, but it only lets oone client connect to the server. What would I change in my code so it would accept multiple clients, not have them wait in a line.

我编写了一个基本的 isnatnt messager 程序,但它只允许一个客户端连接到服务器。我会在我的代码中更改什么,以便它接受多个客户端,而不是让他们排队等候。

Client.java

客户端.java

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

public class Client extends JFrame{

   private JTextField userText;
   private JTextArea chatWindow;
   private ObjectOutputStream output;
   private ObjectInputStream input;
   private String message = "";
   private String serverIP;
   private Socket connection;
   private JTextField UsernameField;
   private String Username;
   Color RED = new Color(255,0,0);
   Color ORANGE = new Color(255,128,0);
   Color YELLOW = new Color(255,255,0);
   Color LIGHT_GREEN = new Color(51,255,51);
   Color GREEN = new Color(0,255,0);
   Color DARK_GREEN = new Color(0,102,0);
   Color LIGHT_BLUE = new Color(51,51,255);
   Color BLUE = new Color(0,0,255);
   Color DARK_BLUE = new Color(0,0,102);
   Color PURPLE = new Color(153,0,153);



   //constructor
   public Client(String host){
      super("Azrin IM");
      serverIP = host;

      userText = new JTextField("Enter Message Here.");
      userText.addMouseListener(new MouseAdapter() {
          public void mouseClicked(MouseEvent e) {
              if (userText.getText().equals("Enter Message Here.")) // User has not entered text yet
                  userText.setText("");
          }
      });



      userText.setEditable(true);
      UsernameField = new JTextField("Enter Username Here.");
      UsernameField.addMouseListener(new MouseAdapter() {
          public void mouseClicked(MouseEvent e) {
              if (UsernameField.getText().equals("Enter Username Here.")) // User has not entered text yet
                  UsernameField.setText("");
          }
      });

      add(new JLabel ("Enter Username Here."));
      UsernameField.setEditable(true);
      userText.addActionListener(
         new ActionListener(){
            public void actionPerformed(ActionEvent event){
                Username = UsernameField.getText();
                sendMessage(event.getActionCommand());
                userText.setText("");
                UsernameField.setText("");
            }
         }
      );
      add(userText, BorderLayout.SOUTH);
      add (UsernameField, BorderLayout.NORTH);
      chatWindow = new JTextArea();
      add(new JScrollPane(chatWindow), BorderLayout.CENTER);
      setSize(400,300);
      setVisible(true);
   }


   //connect to server
   public void startRunning(){
      try{
         connectToServer();
         setupStreams();
         whileChatting();
      }catch(EOFException eofException){
         showMessage("\n Client terminated connection");
      }catch(IOException ioException){
         ioException.printStackTrace();
      }finally{
         Disconnect();
      }
   }

   //connect to server
   private void connectToServer() throws IOException{
      showMessage("Attempting connection... \n");
      connection = new Socket(InetAddress.getByName(serverIP), 6969);
      showMessage("Connected to: " + connection.getInetAddress().getHostName() );
   }

   //set up streams to send and receive messages
   private void setupStreams() throws IOException{
      output = new ObjectOutputStream(connection.getOutputStream());
      output.flush();
      input = new ObjectInputStream(connection.getInputStream());
      showMessage("\n Now connected to Server! \n");
   }

   //while chatting with server
   private void whileChatting() throws IOException{
      ableToType(true);
      do{
         try{
            message = (String) input.readObject();
            showMessage("\n" + message);
         }catch(ClassNotFoundException classNotfoundException){
            showMessage("\n I dont know that object type");
         }
      }while(!message.equals(Username + ": END"));



   }



   //close the streams and sockets
   private void Disconnect(){
      showMessage("\n Disconnected.");
      ableToType(false);
      try{
         output.close();
         input.close();
         connection.close();
      }catch(IOException ioException){
         ioException.printStackTrace();
      }
   }

   //send messages to server
   private void sendMessage(String message){
      try{
         output.writeObject(Username + ": " + message);
         output.flush();
         showMessage("\n" + Username + ": " + message);
         if (message.equals("RED")){
          chatWindow.setForeground(RED);
         }
         if (message.equals("ORANGE")){
              chatWindow.setForeground(ORANGE);
            }
         if (message.equals("YELLOW")){
               chatWindow.setForeground(YELLOW);
           }
         // I am aware I need to space these if staments better :) .
if (message.equals("LIGHT_GREEN")){
     chatWindow.setForeground(LIGHT_GREEN);
 }
if (message.equals("GREEN")){
     chatWindow.setForeground(GREEN);
}
if (message.equals("DARK_GREEN")){
     chatWindow.setForeground(DARK_GREEN);
}
if (message.equals("LIGHT_BLUE")){
     chatWindow.setForeground(LIGHT_BLUE);
}
if (message.equals("BLUE")){
     chatWindow.setForeground(BLUE);
}
if (message.equals("DARK_BLUE")){
     chatWindow.setForeground(DARK_BLUE);
}
if (message.equals("PURPLE")){
     chatWindow.setForeground(PURPLE);
}



      }catch(IOException ioException){
         chatWindow.append("\n something messed up sending message hoss!");
      }
   }

   //change/update chatWindow
   private void showMessage(final String m){
      SwingUtilities.invokeLater(
         new Runnable(){
            public void run(){
               chatWindow.append(m);
            }
         }
      );
   }

   //gives user permission to type crap into the text box
   private void ableToType(final boolean tof){
      SwingUtilities.invokeLater(
         new Runnable(){
            public void run(){
               userText.setEditable(tof);
            }
         }
      );      
   }
}

ClientTest.java

客户端测试程序

import javax.swing.JFrame;

public class ClientTest {
   public static void main(String[] args) {
      Client charlie;
      charlie = new Client("69.125.13.88");
      charlie.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      charlie.startRunning();
   }
}

Server.java

服务器端.java

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

public class Server extends JFrame{

   private JTextField userText;
   private JTextArea chatWindow;
   private ObjectOutputStream output;
   private ObjectInputStream input;
   private ServerSocket server;
   private Socket connection;

   //constructor
   public Server(){
      super("Azrin IM Server");
      userText = new JTextField();
      userText.setEditable(false);
      userText.addActionListener(
         new ActionListener(){
            public void actionPerformed(ActionEvent event){
               sendMessage(event.getActionCommand());
               userText.setText("");
            }
         }
      );
      add(userText, BorderLayout.NORTH);
      chatWindow = new JTextArea();
      add(new JScrollPane(chatWindow));
      setSize(500,200);
      setVisible(true);
   }

   //set up and run the server
   public void startRunning(){
      try{
         server = new ServerSocket(6969, 100);
         while(true){
            try{
               waitForConnection();
               setupStreams();
               whileChatting();
            }catch(EOFException eofException){
               showMessage("\n Server ended the connection! ");
            }finally{
               closeCrap();
            }
         }
      }catch(IOException ioException){
         ioException.printStackTrace();
      }
   }

 //wait for connection, then display connection information
   private void waitForConnection() throws IOException{
      showMessage(" Waiting for someone to connect... \n");
      connection = server.accept();
      showMessage(" Now connected to " + connection.getInetAddress().getHostName());
   }

   //get stream to send and receive data
   private void setupStreams() throws IOException{
      output = new ObjectOutputStream(connection.getOutputStream());
      output.flush();
      input = new ObjectInputStream(connection.getInputStream());
      showMessage("\n Streams are now setup! \n");
   }

   //during the chat conversation
   private void whileChatting() throws IOException{
      String message = " You are now connected! ";
      sendMessage(message);
      ableToType(true);
      do{
         try{
            message = (String) input.readObject();
            showMessage("\n" + message);
         }catch(ClassNotFoundException classNotFoundException){
            showMessage("\n idk wtf that user sent!");
         }
      }while(!message.equals("CLIENT - END"));
   }

   //close streams and sockets after you are done chatting
   private void closeCrap(){
      showMessage("\n Closing connections... \n");
      ableToType(false);
      try{
         output.close();
         input.close();
         connection.close();
      }catch(IOException ioException){
         ioException.printStackTrace();
      }
   }

   //send a message to client
   private void sendMessage(String message){
      try{
         output.writeObject("Josh A - " + message);
         output.flush();
         showMessage("\nSERVER - " + message);
      }catch(IOException ioException){
         chatWindow.append("\n ERROR: DUDE I CANT SEND THAT MESSAGE");
      }
   }

   //updates chatWindow
   private void showMessage(final String text){
      SwingUtilities.invokeLater(
         new Runnable(){
            public void run(){
               chatWindow.append(text);
            }
         }
      );
   }

   //let the user type stuff into their box
   private void ableToType(final boolean tof){
      SwingUtilities.invokeLater(
         new Runnable(){
            public void run(){
               userText.setEditable(tof);
            }
         }
      );
   }

}

ServerTest.java

服务器测试程序

import javax.swing.JFrame;

public class ServerTest {
   public static void main(String[] args) {
      Server sally = new Server();
      sally.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      sally.startRunning();
   }

}

}

回答by MadProgrammer

Plain Thread Example

普通螺纹示例

This is "plain" thread example, is probably among the more common examples you might find. The problem with this is you can lose control of threads and have hundreds of ramped threads all running about, consuming system resources...

这是“普通”线程示例,可能是您可能会发现的更常见的示例之一。这样做的问题是您可能会失去对线程的控制,并且有数百个倾斜的线程都在运行,消耗系统资源......

It is simple and does demonstrate the basic concept of what you need to achieve...

它很简单,并且确实展示了您需要实现的基本概念......

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class TestSocketThread {

    // Need away to stop the program...
    private static boolean acceptMore = true;

    public static void main(String[] args) {
        new TestSocketThread();
    }

    public TestSocketThread() {
        ServerSocket serverSocket = null;
        try {
             serverSocket = new ServerSocket(6969, 100);
            while (acceptMore) {
                Socket socket = serverSocket.accept();
                new Thread(new SocketThread(socket)).start();    
            }
        } catch (IOException exp) {
            exp.printStackTrace();
        } finally {
            try {
                serverSocket.close();
            } catch (Exception e) {
            }
        }
    }

    public class SocketThread implements Runnable {

        private Socket socket;

        public SocketThread(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            // Process socket...
        }
    }
}

Executor Service Example

Executor 服务示例

The executor services are more flexible and provide better management control over plain threads, including (as per this example) a fixed thread pool.

执行程序服务更灵活,并提供对普通线程更好的管理控制,包括(根据本示例)固定线程池。

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExecutorSocketTest {

    // Need away to stop the program...
    private static boolean acceptMore = true;

    public static void main(String[] args) {
        new ExecutorSocketTest();
    }

    public ExecutorSocketTest() {
        ServerSocket serverSocket = null;
        ExecutorService executorService = Executors.newFixedThreadPool(100);
        try {
             serverSocket = new ServerSocket(6969, 100);
            while (acceptMore) {
                Socket socket = serverSocket.accept();
                executorService.submit(new SocketCallable(socket));
            }
        } catch (IOException exp) {
            exp.printStackTrace();
        } finally {
            try {
                serverSocket.close();
            } catch (Exception e) {
            }
            executorService.shutdownNow();
        }
    }

    /**
     *
     * @author swhitehead
     */
    public class SocketCallable implements Callable {

        private Socket socket;

        public SocketCallable(Socket socket) {
            this.socket = socket;
        }

        @Override
        public Object call() throws Exception {
            // Process socket requests...
            return null;
        }
    }
}

Your job is to now go away and read all about Concurrency in Java

您现在的工作是离开并阅读有关Java 并发的所有内容