使用特定活动线程发送到服务器

时间:2018-04-13 23:12:17

标签: java multithreading client-server java-threads

我有这个类,我尝试创建一些线程,然后我需要message发送server所有threads或使用特定{{1} }}。我似乎无法通过这种方式找到方法,我只能使用创建的最后thread发送。

  

这是班级:

thread
  

这是客户端线程类:

 public class test{

  public test(){

  }

  public static void main(String[] args){
    MultiThreadChatClient mc = new MultiThreadChatClient();
    test st =  new test();
    for(int i =0; i<=4; i++){
       mc.createThreads();
     }


    while (true) {

          System.out.print("type your message: ");
          Scanner s = new Scanner(System.in);
          String ss = s.nextLine();
          ss = ss.trim().replaceAll(" +", " ");

            mc.sendMessage(ss);

try 
{
    Thread.sleep(400);
} 
catch(InterruptedException e)
{
     // this part is executed when an exception (in this example InterruptedException) occurs
  System.out.println("Exeption: " + e);
}

     }      
}

}
  

这是服务器代码:

  public class MultiThreadChatClient implements Runnable {

  // The client socket
  private static Socket clientSocket = null;
  // The output stream
  private static PrintStream os = null;
  // The input stream
  private static BufferedReader br;

  private static BufferedReader inputLine = null;
  private static boolean closed = false;


  public static void main(String[] args) {

    // The default port.
    int portNumber = 2222;
    // The default host.
    String host = "localhost";

    if (args.length < 2) {
      System.out.println("Usage: java MultiThreadChatClient <host> <portNumber>\n"
              + "Now using host=" + host + ", portNumber=" + portNumber);
    } else {
      host = args[0];
      portNumber = Integer.valueOf(args[1]).intValue();
    }
  }



    /*
     * Open a socket on a given host and port. Open input and output streams.
     */

    public void createThreads(){
    try {
      clientSocket = new Socket("localhost", 2222);
      inputLine = new BufferedReader(new InputStreamReader(System.in));
      os = new PrintStream(clientSocket.getOutputStream());
      br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
    } catch (UnknownHostException e) {
      System.err.println("Don't know about host " + 2222);
    } catch (IOException e) {
      System.err.println("Couldn't get I/O for the connection to the host " + 2222);
    }
  //}

    /*
     * If everything has been initialized then we want to write some data to the
     * socket we have opened a connection to on the port portNumber.
     */
    if (clientSocket != null && os != null && br != null) {

        new Thread(new MultiThreadChatClient()).start();

    }
  }
          public void sendMessage(String mes){
          os.println(mes);
          }

  /*
   * Create a thread to read from the server. (non-Javadoc)
   * 
   * @see java.lang.Runnable#run()
   */
  public void run() {
    /*
     * Keep on reading from the socket till we receive "Bye" from the
     * server. Once we received that then we want to break.
     */
    String responseLine;
    try {
      while ((responseLine = br.readLine()) != null){

        System.out.println(responseLine);

        if (responseLine.indexOf("*** Bye") != -1)
          break;
      }
      closed = true;
    } catch (IOException e) {
      System.err.println("IOException1234:  " + e);
    }
  }
}

那么,有没有办法创建5个线程,然后在所有线程上发送消息或从中选择一个特定的线程?

1 个答案:

答案 0 :(得分:1)

为了能够拥有一个能够启动多个会话的客户端,并且能够将数据发送到其中一个或多个会话,客户端必须以一些方式进行更改。

  1. 必须删除客户端中的静态引用。
  2. 必须创建Socket实例并将其存储在主线程中(编写器将用于代表一个或多个客户端会话发送消息)
  3. 每个客户端会话现在只负责阅读(读者通过构造函数传递)。
  4. 代码基于您的原始代码,并且是进一步增强的模板:它将管理5个客户端会话,并且能够写入1个或多个。

    新的主线程(例如,扫描器将首先询问客户端#1的消息,然后2,3,4和下一个将在循环中向所有人广播):

    public class MultiThreadChatClientRunner {
    
    final int NO_CLIENTS = 5;
    //final String HOST_IP = "192.168.2.7";
    final String HOST_IP = "localhost";
    
    public static void main(String[] args) {
    
        new MultiThreadChatClientRunner().start();
    
    }
    
    private void start() {
    
        Socket[] sockets = new Socket[NO_CLIENTS];
        PrintStream[] writers = new PrintStream[NO_CLIENTS];
        BufferedReader[] readers = new BufferedReader[NO_CLIENTS];
    
        for (int i = 0; i < NO_CLIENTS; i++) {
            System.out.println("Creating client number "+i);
            Socket clientSocket;
            try {
                clientSocket = new Socket(HOST_IP, 2222);
                writers[i] = new PrintStream(clientSocket.getOutputStream());
                readers[i] = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                new Thread(new MultiThreadChatClient(i, readers[i])).start();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        int clientId = 0;
        Scanner s = new Scanner(System.in);
        while (true) {
    
            System.out.print("type your message for client #"+clientId);
            String ss = s.nextLine();
            ss = ss.trim().replaceAll(" +", " ");
    
            writers[clientId].println(ss);
            clientId = (clientId+1)%NO_CLIENTS;
    
            // Test to broadcast to all clients
            if (clientId == 4) {
                for (int i = 0; i<NO_CLIENTS; i++)
                    writers[i].println("Broadcast message: "+ss);
            }
    
            try {
                Thread.sleep(400);
            } catch (InterruptedException e) {
                System.out.println("Thread was interrupted");
                break;
            }
        }
        s.close();
    }
    
    }
    

    新客户端,比以前简单得多:

    public class MultiThreadChatClient implements Runnable {
    
    // The client socket
    private Socket clientSocket = null;
    // The output stream
    private PrintStream os = null;
    // The input stream
    private final BufferedReader br;
    private final int clientId;
    
    public MultiThreadChatClient(int clientId, BufferedReader br) {
        super();
        this.clientId = clientId;
        this.br = br;
    }
    
    /*
     * Create a thread to read from the server. (non-Javadoc)
     * 
     * @see java.lang.Runnable#run()
     */
    public void run() {
        /*
         * Keep on reading from the socket till we receive "Bye" from the
         * server. Once we received that then we want to break.
         */
        String responseLine;
        try {
            while ((responseLine = br.readLine()) != null) {
    
                System.out.printf("Client #%d received message=%s\n", clientId, responseLine);
    
                if (responseLine.indexOf("*** Bye") != -1)
                    break;
            }
        } catch (IOException e) {
            System.err.println("IOException1234:  " + e);
        }
    }
    }
    

    服务器几乎相同,但管理得更好,并且有更多的日志记录来显示哪个客户端正在通信。

    public class MultiThreadChatServerSync {
    
    // The server socket.
    private static ServerSocket serverSocket = null;
    // The client socket.
    private static Socket clientSocket = null;
    
    // This chat server can accept up to maxClientsCount clients' connections.
    private static final int maxClientsCount = 50;
    private static final ClientThread[] threads = new ClientThread[maxClientsCount];
    
    public static void main(String args[]) {
    
        // The default port number.
        int portNumber = 2222;
        if (args.length < 1) {
            System.out.println(
                    "Usage: java MultiThreadChatServerSync <portNumber>\n" + "Now using port number=" + portNumber);
        } else {
            portNumber = Integer.valueOf(args[0]).intValue();
        }
    
        /*
         * Open a server socket on the portNumber (default 2222). Note that we
         * can not choose a port less than 1023 if we are not privileged users
         * (root).
         */
        try {
            serverSocket = new ServerSocket(portNumber);
            // System.out.println(serverSocket.getPort());
        } catch (IOException e) {
            System.out.println(e);
        }
    
        /*
         * Create a client socket for each connection and pass it to a new
         * client thread.
         */
        while (true) {
            try {
                System.out.println("Awaiting a new connection on "+serverSocket.getLocalPort());
                clientSocket = serverSocket.accept();
                int i = 0;
                for (i = 0; i < maxClientsCount; i++) {
                    if (threads[i] == null) {
                        (threads[i] = new ClientThread(i, clientSocket)).start();
                        // System.out.println("A new client is created");
                        break;
                    }
                }
                if (i == maxClientsCount) {
                    PrintStream os = new PrintStream(clientSocket.getOutputStream());
                    os.println("Server too busy. Try later.");
                    os.close();
                    clientSocket.close();
                }
            } catch (IOException e) {
                System.out.println(e);
            }
        }
    }
    }
    
    class ClientThread extends Thread {
    
    private BufferedReader br = null;
    private PrintStream os = null;
    private final Socket clientSocket;
    private final int clientId;
    
    public ClientThread(int clientId, Socket clientSocket) {
        this.clientSocket = clientSocket;
        this.clientId = clientId;
    }
    
    public void run() {
    
        try {
            /*
             * Create input and output streams for this client.
             */
            br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            os = new PrintStream(clientSocket.getOutputStream());
    
            String line = "";
            while ((line = br.readLine()) != null) {
                System.out.printf("Client <%d> received message=<%s> via Client port: <%d>\n", clientId, line, clientSocket.getPort());
                // Echo it back (as a test)
                os.println(line);
            }
            br.close();
            os.close();
            clientSocket.close();
    
        } catch (IOException e) {
        }
        System.out.println("Client has closed the session");
    }
    }
    

    如果您现在有任何其他问题,请与我们联系。