0

Quite simple I want to create a chatroom that accepts multiple clients all of which can assign their own ID. Whenever they input anything it is sent to all users. Currently I have a echo client server where the client inputs something and it is echoed back. My first question is how do I allow a user to give himself a username? obviously I need a variable somewhere that accepts the name what class do you recommend I put this in? and how would I get the name itself Something like if (theInput.equalsIgnoreCase("username" : ""))

Then all that I need to do is echo what the client says to all clients. I'm at a loss of how to do this so any advice would be much appreciated. Although I've found some tutorials and example code online I don't understand it and I don't feel comfortable using it if I don't understand even if it does work. Thanks

Here is my code: EchoClient

'// echo client
import java.util.Scanner;
import java.io.*;
import java.net.*;
public class EchoClient {
public static void main(String[] args) throws IOException { 
    Socket echoSocket = null;
    //PrintWriter socketOut = null;
    try {
        echoSocket = new Socket("127.0.0.1", 4444); // connect to self at port 4444
        System.out.println("Connected OK");
        Scanner socketIn = new Scanner(echoSocket.getInputStream());  // set up input from socket
        PrintWriter socketOut = new PrintWriter(echoSocket.getOutputStream(), true);    // set up output to socket
        Scanner kbdIn = new Scanner(System.in);     // Scanner to pick up keyboard input
        String serverResp = "";
        String userInput = kbdIn.nextLine();        // get input from the user

        while (true) {
            socketOut.println(userInput);                   // send user input to the socket
            serverResp =  socketIn.nextLine();     // get the response from the socket
            System.out.println("echoed back: " + serverResp);   // print it out
            if (serverResp.equals("Closing connection")) { break; } //break if we're done
            userInput = kbdIn.nextLine();   // get next user input
        }
        socketOut.close();
        kbdIn.close();
        socketIn.close();
    }
    catch (ConnectException e) {
        System.err.println("Could not connect to host");
        System.exit(1);
    }
    catch (IOException e) {
        System.err.println("Couldn't get I/O for connection");
        System.exit(1);
    }
    echoSocket.close();
} 

}'

EchoServer

// multiple (threaded) server
import java.net.ServerSocket;
import java.net.Socket;
public class EchoServerMult {
public static void main(String[] args) throws Exception {
    ServerSocket serverSocket = new ServerSocket(4444);   // create server socket on this machine
    System.err.println("Started server listening on port 4444");
    while (true) {        // as each connection is made, pass it to a thread
        //new EchoThread(serverSocket.accept()).start();  // this is same as next 3 lines
        Socket x = serverSocket.accept();   // block until next connection
        EchoThread et = new EchoThread(x);
        et.start();  
        System.err.println("Accepted connection from client");
    }
}

}

EchoThread

// thread to handle one echo connection
import java.net.*;
import java.io.*;
import java.util.Scanner;
public class EchoThread extends Thread {
private Socket mySocket = null;

public EchoThread(Socket socket) {       // constructor method
    mySocket = socket;
}
public void run() {
    try {
        PrintWriter out = new PrintWriter(mySocket.getOutputStream(), true);
        Scanner in = new Scanner(mySocket.getInputStream());
        String inputLine;
        while (true) {
            inputLine = in.nextLine();      
            if (inputLine.equalsIgnoreCase("Bye")) {
                out.println("Closing connection");
                break;      
            } else {
                out.println(inputLine);
            }
        }
        out.close();
        in.close();
        mySocket.close(); 
    } catch (Exception e) {
        System.err.println("Connection reset");   // bad error (client died?)
    }
}

}

Bernhard Barker
  • 54,589
  • 14
  • 104
  • 138
James
  • 139
  • 3
  • 7
  • 1
    Hi - 1) I'm not sure if this is just a "fun experiment", a homework assignment ... or if you actually want to create a chat room that people can use. If the latter, I'd strongly encourage you to consider writing a web app: for example, use Tomcat and .jsp. 2) Q: "echo what the client says to all clients?" A: Create some kind of "list" for each client. At a minimum, you'll need a) user name, and b) IP address or socket. – paulsm4 Dec 21 '12 at 07:18

1 Answers1

2

The easiest would probably be to have a common class that all the clients are connected to (when they are created) using the observer pattern. The link even gives some java code.

To have clients have a username, the easiest would just be to have the first message the server sends be "Enter your desired username:", and just take the return value as is. Otherwise you can just use inputLine.substring(int) to get the username from username:{username}. You can store the username inside EchoThread. Avoiding duplicate usernames would require you store a set of usernames in EchoServer. You can then pass the username to the Observable class along with the message.

Currently your program works with sequential messaging, as in the client and server alternate in sending messages (more concretely, the client sends a message, then the server sends the same message back). You'll need to change this so the client can receive messages at any time. You can do this by creating a thread on the client side that either just sends or just receives (and do the other in the client itself). In client:

...
System.out.println("Connected OK");
PrintWriter socketOut = new PrintWriter(echoSocket.getOutputStream(), true);    // set up output to socket
new ReceiverThread(echoSocket).start();
while (true)
{
   String userInput = kbdIn.nextLine();        // get input from the user
   socketOut.println(userInput);                   // send user input to the socket
}
...

ReceiverThread run method inside try ... catch: (the rest looks identical to EchoThread)

Scanner in = new Scanner(mySocket.getInputStream());
while (true)
{
   String inputLine = in.nextLine();      
   if (inputLine.equalsIgnoreCase("Bye"))
   {
      out.println("Closing connection");
      System.exit(0);      
   }
   else
   {
      out.println(inputLine);
   }
}

System.exit() is probably not the best idea, but this is just to give you some idea of what to do.

Bernhard Barker
  • 54,589
  • 14
  • 104
  • 138