服务器等待直到存在特定数量的客户端

时间:2018-05-31 23:55:29

标签: java multithreading client-server

我想在一个简单的多线程客户端 - 服务器应用程序中实现的是服务器对连接进行计数,当它达到一定数量时,假设为2,它将为每个客户端创建一个线程(所以2个连接意味着2个线程)负责从客户端读取消息并将消息广播到所有其他客户端。以下是我在多线程客户端 - 服务器示例中所做的修改:

SERVER:

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

/*
 * A chat server that delivers public and private messages.
 */
public class Server_X_Client {

  // 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 numOfClients = 2;
  private static final clientThread[] threads = new clientThread[numOfClients];
  private static final Socket[] sockets = new Socket [numOfClients];

  public static void main(String args[]) throws InterruptedException {

    // The default port number.
    int portNumber = 2222;
    int count=0;
    /*
     * 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);
    } 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 {

        clientSocket = serverSocket.accept();
        int i = 0;

        for (i = 0; i < numOfClients; i++) {
          if (sockets[i] == null) {

              PrintStream os = new PrintStream(clientSocket.getOutputStream());
              DataInputStream in = new DataInputStream (clientSocket.getInputStream());
              os.println("Enter your name: ");
              String name = in.readLine().trim();
              os.println("Enter server password: ");
              String psw = in.readLine().trim();

              if(psw.equals("Pelin")){
                  os.println("Password is correct+ "+ i+" pls wait..");
                  sockets[i] = clientSocket;
              }else{
                  os.println("Password is wrong..");
              }
            break;
          }
        }
        if (i == numOfClients-1) {

            for (int j=0;j<numOfClients;j++){
                if(threads[j]==null){

            (threads[j] = new clientThread(sockets[j], threads)).start();


                //threads[j].join();

        }
        }
        }
      } catch (IOException e) {
        System.out.println(e);
      }
    }
  }
}

/*
 * The chat client thread. This client thread opens the input and the output
 * streams for a particular client, ask the client's name, informs all the
 * clients connected to the server about the fact that a new client has joined
 * the chat room, and as long as it receive data, echos that data back to all
 * other clients. When a client leaves the chat room this thread informs also
 * all the clients about that and terminates.
 */
class clientThread extends Thread {

  private DataInputStream is = null;
  private PrintStream os = null;
  private  Socket clientSocket = null;
  private clientThread[] threads;
  private  int maxClientsCount;

  public clientThread(Socket clientSocket, clientThread[] threads) {
    this.clientSocket = clientSocket;
    this.threads = threads;
    maxClientsCount = threads.length;
  }

  public void run() {
    int maxClientsCount = this.maxClientsCount;
    clientThread[] threads = this.threads;

    try {
      /*
       * Create input and output streams for this client.
       */
      is = new DataInputStream(clientSocket.getInputStream());
      os = new PrintStream(clientSocket.getOutputStream());
      for (int i = 0; i < maxClientsCount; i++) {
        if (threads[i] != null && threads[i] != this) {
          threads[i].os.println("READY!!);
        }
      }
      while (true) {
        String line = is.readLine();
        if (line.startsWith("/quit")) {
          break;
        }
        for (int i = 0; i < maxClientsCount; i++) {
          if (threads[i] != null) {
            threads[i].os.println("Someone:" + line);
          }
        }
      }
      for (int i = 0; i < maxClientsCount; i++) {
        if (threads[i] != null && threads[i] != this) {
          threads[i].os.println("*** The user " +"XXX"
              + " is leaving the chat room !!! ***");
        }
      }
      os.println("*** Bye "+" ***");

      /*
       * Clean up. Set the current thread variable to null so that a new client
       * could be accepted by the server.
       */
      for (int i = 0; i < maxClientsCount; i++) {
        if (threads[i] == this) {
          threads[i] = null;
        }
      }

      /*
       * Close the output stream, close the input stream, close the socket.
       */
      is.close();
      os.close();
      clientSocket.close();
    } catch (IOException e) {
    }
  }
}

客户端:

import java.io.DataInputStream;
import java.io.PrintStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

public class NetworkClient implements Runnable {
// The client socket
private static Socket clientSocket = null;
// The output stream
private static PrintStream os = null;
// The input stream
private static DataInputStream is = null;

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";
    Scanner sc = new Scanner(System.in);

    System.out.println("Connecting to " + host + " on port " + portNumber);

    /*
     * Open a socket on a given host and port. Open input and output
     * streams.
     */
    try {
        clientSocket = new Socket(host, portNumber);
        inputLine = new BufferedReader(new InputStreamReader(System.in));
        os = new PrintStream(clientSocket.getOutputStream());
        is = new DataInputStream(clientSocket.getInputStream());
    } catch (UnknownHostException e) {
        System.err.println("Don't know about host " + host);
    } catch (IOException e) {
        System.err.println("Couldn't get I/O for the connection to the host " + host);
    }

    /*
     * 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 && is != null) {
        try {

            /* Create a thread to read from the server. */
            new Thread(new NetworkClient()).start();
            while (!closed) {

                os.println(inputLine.readLine().trim());
            }
            /*
             * Close the output stream, close the input stream, close the
             * socket.
             */
            os.close();
            is.close();
            clientSocket.close();
        } catch (IOException e) {
            System.err.println("IOException:  " + e);
        }
    }

}

/*
 * 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 = is.readLine()) != null) {
            System.out.println(responseLine);
            if (responseLine.indexOf("bye") != -1)
                break;
        }
        closed = true;
    } catch (IOException e) {
        System.err.println("IOException:  " + e);
    }
}

}

服务器端当前存在的错误是Thread-Null指针异常;在clientThread类中,当服务器尝试通过写“READY!”来通知所有其他客户端时信息。好像有同步问题。虽然我在输出流上写之前检查thread [i]是否为null,但它会通过此检查,当它尝试编写线程[i] .os.println(“READY !!)时,会发生错误。感谢任何帮助。

0 个答案:

没有答案