'Simple Java Chat Server

I am making a TCP chat server from a simple tutorial I found and I'm kind of new to java. I will eventually make a client class but I've been testing it through telnet so far. I have a couple of problems. I have setup the server to take commands from the client. For example "EXIT" which closes the client connection, and "Username" which prints "OK". Shown below:

USER 1: TIM

Welcome to Bob's Chat Server!

Please Enter a User Name: 
Tim
Welcome Tim we hope you enjoy your chat today
Bob:Hello
Hi Bob
Tim
OK
EXIT
Closing Connection  . . . Goodbye

USER 2: BOB

Welcome to Bob's Chat Server!

Please Enter a User Name: 
Bob
Welcome Bob we hope you enjoy your chat today
Hello
Tim:Hi Bob
Tim:Tim

I have three problems that I want to address:

  1. You'll notice that when USER 1 typed "Tim" (his username) it said "OK" like I wanted, but it also printed "Tim" to USER 2. Is there a way to make it not send my typed commands across? So when I type "Tim" it doesn't print "Tim" to USER 2?

  2. When messages are sent to other users it displays who said it. Is there a way to print the name on both connections? For example when USER 2 says "Hello" it looks more like "Bob: Hello" on both connections?

  3. Is there a way to keep track of everything that's said in the entire chat session and print off the entire contents of the chat to whatever user requested it?

Here is my server code:

// Chat Server runs at port no. 9020
import java.io.*;
import java.util.*;
import java.net.*;
import static java.lang.System.out;

public class  TCPServer 
{
  Vector<String> users = new Vector<String>();
  Vector<HandleClient> clients = new Vector<HandleClient>();

  int PORT = 9020;
  int NumClients = 10;

  public void process() throws Exception  
  {
      ServerSocket server = new ServerSocket(PORT,NumClients);
      out.println("Server Connected...");
      while( true) 
      {
         Socket client = server.accept();
         HandleClient c = new HandleClient(client);
         clients.add(c);
     }  // end of while
  }

  public static void main(String ... args) throws Exception 
  {
      new TCPServer().process();
  } // end of main

  public void boradcast(String user, String message)  
  {
        // send message to all connected users
        for (HandleClient c : clients)
           if (!c.getUserName().equals(user))
           {
              c.sendMessage(user,message);
           }
  }

  class HandleClient extends Thread 
  {
    String name = "";
    BufferedReader input;
    PrintWriter output;

    public HandleClient(Socket client) throws Exception 
    {
          // get input and output streams
         input = new BufferedReader(new InputStreamReader(client.getInputStream())) ;
         output = new PrintWriter (client.getOutputStream(),true);
         output.println("Welcome to Bob's Chat Server!\n");
         // read name
         output.println("Please Enter a User Name: ");
         name  = input.readLine();
         users.add(name); // add to vector
         output.println("Welcome "+name+" we hope you enjoy your chat today");
         start();
    }

    public void sendMessage(String uname,String  msg)  
    {
        output.println( uname + ":" + msg);
    }

    public String getUserName() 
    {  
        return name; 
    }

    public void run()  
    {
         String line;
         try    
         {
            while(true)   
            {
                        line = input.readLine();
                if("EXIT".equals(line))
            {
                output.println("Closing Connection  . . . Goodbye");
                            clients.remove(this);
                        users.remove(name);
                break;
                    }
            else if(name.equals(line))
            {
                            output.println("OK");
                    }
                boradcast(name,line); // method  of outer class - send messages to all
            }// end of while
         } // try
         catch(Exception e) 
         {
           System.out.println(e.getMessage());
         }
    } // end of run()
  } // end of inner class
} // end of Server

Any help is appreciated. Thanks.



Solution 1:[1]

Is there a way to make it not send my typed commands across? So when I type "Tim" it doesn't print "Tim" to USER 2?

You already store the user name in HandleClient; when its run method gets input, it checks to see if the user has typed his name. So don't call broadcast if he does that, or if he enters a command.

When messages are sent to other users it displays who said it. Is there a way to print the name on both connections? For example when USER 2 says "Hello" it looks more like "Bob: Hello" on both connections?

Most chat clients I've seen have a multiline window to hold the conversation and a small one for entering text. The user enters his text in the small window, and the server broadcasts it back to him. So the server can prepend the username and colon before each message as it is broadcast, and that will be separate from what the user types in on his own client.

Is there a way to keep track of everything that's said in the entire chat session and print off the entire contents of the chat to whatever user requested it?

Sure. Write it all to a file as you go. Look at java.io.FileWriter.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 arcy