简体   繁体   中英

Client threads can send only one message and stop

I have two java classes one for that reads from the client threads and one that creates the client threads.. So, if i open n clients at the same time, the clients from 0 to n-1 can send only one message and then they can only receive while the n-th client can keep sending as much as he wants!

here's the server code:

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

/*
 * A chat server that delivers public and private messages.
 */
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 = 10;
  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);
    } 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 < maxClientsCount; i++) {
          if (threads[i] == null) {
            (threads[i] = new clientThread(clientSocket, threads)).start();
            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 {
MultiThreadChatServerSync ms = new MultiThreadChatServerSync();
  private String clientName = null;
  //private DataInputStream is = null;
   private BufferedReader br = null;
  private PrintStream os = null;
  private Socket clientSocket = null;
  private final clientThread[] threads;
  private int maxClientsCount;

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

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

    try {
      /*
       * Create input and output streams for this client.
       */
      //is = new DataInputStream(clientSocket.getInputStream());
      br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
      os = new PrintStream(clientSocket.getOutputStream());
      String name;
      while (true) {
        System.out.println("Inside the while.. to send back the name");
        os.println("Enter your name.");
        System.out.println("Inside the while.. the name is sent");

        name = br.readLine().trim();
        if (name.indexOf('@') == -1) {
          break;
        } else {
          os.println("The name should not contain '@' character.");
        }
      }

      /* Welcome the new the client. */
      System.out.println(name  + " waas joined");
      os.println("Welcome " + name
          + " to our chat room.\nTo leave enter /quit in a new line.");
      synchronized (this) {
        for (int i = 0; i < maxClientsCount; i++) {
          if (threads[i] != null && threads[i] == this) {
            clientName = "@" + name;
            break;
          }
        }
        for (int i = 0; i < maxClientsCount; i++) {
          if (threads[i] != null && threads[i] != this) {
            threads[i].os.println("*** A new user " + name
                + " entered the chat room !!! ***");
          }
        }
      }
      /* Start the conversation. */
      while (true) {
        String line = br.readLine();
        System.out.println("message: " + line);
        os.println("your message is received");
        if (line.startsWith("/quit")) {
          break;
        }
        /* If the message is private sent it to the given client. */
        if (line.startsWith("@")) {
          String[] words = line.split("\\s", 2);
          if (words.length > 1 && words[1] != null) {
            words[1] = words[1].trim();
            if (!words[1].isEmpty()) {
              synchronized (this) {
              //  System.out.println("The message received is0: " + words[1]);
                for (int i = 0; i < maxClientsCount; i++) {
                 // System.out.println("The message received is1: " + words[1]);
                  if (threads[i] != null && threads[i] != this
                      && threads[i].clientName != null
                      && threads[i].clientName.equals(words[0])) {
                    threads[i].os.println("<" + name + "> " + words[1]);
                    /*
                     * Echo this message to let the client know the private
                     * message was sent.
                     */
                   // System.out.println("The message received is2: " + words[1]);
                    this.os.println(">" + name + "> " + words[1]);
                    break;
                  }
                }
              }
            }
          }
        } else {
          /* The message is public, broadcast it to all other clients. */
          synchronized (this) {
            for (int i = 0; i < maxClientsCount; i++) {

              if (threads[i] != null && threads[i].clientName != null) {
                //System.out.println("Client name: " + threads[i].clientName);
                threads[i].os.println("<" + name + "> " + line);
              }
            }
          }
        }
      }
      synchronized (this) {
        for (int i = 0; i < maxClientsCount; i++) {
          if (threads[i] != null && threads[i] != this
              && threads[i].clientName != null) {
            threads[i].os.println("*** The user " + name
                + " is leaving the chat room !!! ***");
          }
        }
      }
      os.println("*** Bye " + name + " ***");

      /*
       * Clean up. Set the current thread variable to null so that a new client
       * could be accepted by the server.
       */
      synchronized (this) {
        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.
       */
      br.close();
      os.close();
      clientSocket.close();
    } catch (IOException e) {
    }
  }
}

And this is the Client Code:

   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 MultiThreadChatClient 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 br;

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

  public static void main(String[] args) {

      MultiThreadChatClient mc = new MultiThreadChatClient();
    // 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.
     */
    try {
      clientSocket = new Socket(host, portNumber);
    //  System.out.println("The socket is opened..");
      inputLine = new BufferedReader(new InputStreamReader(System.in));
      os = new PrintStream(clientSocket.getOutputStream());
      //is = new DataInputStream(clientSocket.getInputStream());
      br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
     //  System.out.println("The buffer reader is opened..");
    } 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 && br != null) {
      try {

        /* Create a thread to read from the server. */
      //  System.out.println("The thread is opening..");;
        new Thread(new MultiThreadChatClient()).start();
      //  System.out.println("The thread is opened..");

        while (!closed) {
         // Scanner s = new Scanner(System.in);
         // String ss = s.nextLine();
          os.println(mc.inputLine.readLine().trim());
          //os.println(ss);
          // System.out.println("The message is sent");
        }
        /*
         * Close the output stream, close the input stream, close the socket.
         */
        os.close();
        br.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.
     */
    //MultiThreadChatClient mcc = new MultiThreadChatClient();
    String responseLine;
    try {
      System.out.println("Insde the run..");
      //os.println(inputLine.readLine());
      while ((responseLine = br.readLine()) != null){
        System.out.println("responseLine: " + responseLine);
        System.out.println(responseLine);
        if (responseLine.indexOf("*** Bye") != -1)
          break;
      }
      closed = true;
    } catch (IOException e) {
      System.err.println("IOException:  " + e);
    }
  }
}

I find this weird since the other clients can still receive the messages but can't send more than one!

As @John123 stated it probably is because you declare the Buffered Reader as static. When you do that there exists only one Buffered Reader across all MultiThreadChatClients. if you change one then you change all of them. The problem you are running into right now is because you don't declare mcc.br at any point. you can change this line

mc.br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

to this

mcc.br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

to fix that or add a declaration to mcc.br in a constructor.

I am only posting this as an answer because I don't have enough rep to comment. Also I would recommend changing the question back to include the buffered reader being static so that the question and answer makes sense.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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