Simple Java Chat Server

I am making a TCP chat server from a simple tutorial that I found, and I'm a little new to java. I will eventually create a client class, but so far have tested it through telnet. I have a couple of problems. I configured the server to execute commands from the client. For example, "EXIT", which closes the client connection, and "Username", which prints "OK." The following is shown:

USER 1: TIM

Welcome to Bob 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 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 solve:

  • You will notice that when USER 1 printed “Tim” (his username), he said “OK” as I wanted, but also printed “Tim” in USER 2. Is there any way to do this without sending my typed commands? So when I type Tim, it doesn't print Tim in USER 2?

  • When messages are sent to other users, it shows who said it. Is there a way to print the name in both connections? For example, when USER 2 says “Hello”, is it more like “Bob: Hello” to both connections?

  • Is there a way to keep track of everything that was said during the entire chat session and print the entire contents of the chat to any user who 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 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. Thank you

+4
source share
2 answers

I changed your code to my liking, see:

For point 1:

 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"); } else { // Seems to me just adding this else part will do the trick for point one. boradcast(name,line); // method of outer class - send messages to all } }// end of while } // try catch(Exception e) { System.out.println(e.getMessage()); } } 

For item 2:

It seems to me that you are typing on the console to get input, in this case, at least at a time you need to type what you have to send to the other side, then you can add your modification to this, as shown in the first method line, broadcast (); so that you can satisfy your need for point 2 or ( else. You can let the server side send it back to the client, a message containing the name, it will send the message to the server as the client, and the server will send all customers back. )

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

And for point 3, you can write your conversation to a file or save it in a database that is always suitable for you.

And since you said you were new to Java, you'd better look at java.nio . This package is better than the previous java.io package.

LAST CHANGE:

Try this small code example, hope this can do what you ask for:

 import java.io.*; public class StringConsole { public static void main(String... args) throws IOException { int count = 0; BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); while (count < 5) { System.out.print("My Name : "); String message = br.readLine(); count++; } } } 

Hope this can help you in some way.

Hi

+2
source

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

You have already saved the username in HandleClient; when his launch method is entered, he checks to see if the user has typed his name. Therefore, do not call the broadcast if he does this, or if he enters a command.

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

Most of the chat clients I've seen have a multi-line window to hold a conversation, and a small one to enter text. The user enters his text in a small window, and the server passes it back to him. Thus, the server can add a username and a colon before each message as it is broadcast, and this will be different from what the user types on his own client.

Is there a way to track everything that was said throughout the chat and print the entire contents of the chat the user requested it to?

Sure. Write everything to a file as it arrives. Take a look at java.io.FileWriter.

+1
source

Source: https://habr.com/ru/post/1393680/


All Articles