Chat application problem
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 12 of 12

Thread: Chat application problem

  1. #1
    Join Date
    Dec 2009
    Posts
    5

    Chat application problem

    Hi guys, I have designed a simple text chat application but i am expereincing problems with it. I will explain.

    Now I have 5 files. IntroFrame.java, Server.java, Server_thread.java, Client.java, and ListClients.java

    Now to run the appliication, you need to compile and then run the IntroFrame.java file. This file opens a GUI that asks the user to select if the pc is the client or server. So the server option is selected. Once this is done, the server begins to run. The next step is to run the client. When the client is run, it must enter the server's hostname to connect, in this case it is 'localhost'. once this has been entered, it asks the user to select a nickname. PLEASE NOTE: for this part, the user has to enter 'Login: " followed by the desired nickname. If the nickname is not in use, then the server accepts the client. Once this is done the user can send messages by typing 'Post" followed by the message.

    Now the problem I have is with regards to running 2 clients. When 2 clients are connected, if client A sends a message by typing 'Post...." the message should be sent to all connected clients. But in my application, the other clients do not receive the message. I have gone through my code a million times and I can't figure out why it doesnt work. I have pasted the Server.java, Server_thread.java, and Client.java file codes below. Could someone please take a look at it and let me know what the problem is? why does it not send the message to all connected clients? Any help would be appreciated. Thank you

    Server.java

    import java.net.*;
    import java.io.*;
    import java.util.*;

    public class Server
    {
    static Vector clients;
    static Socket clientSocket;

    public static void start_server()
    {

    //setting up the server socket to listen on a specified port

    clients = new Vector(); //this creates a reference to a vector object. This will be used to store the list of clients connected to the server
    ServerSocket ss = null; //this creates a reference to a ServerSocket object
    boolean listening = true; //this creates a reference toa boolean object
    clientSocket = null;

    try
    {
    ss = new ServerSocket(9999); //this creates a new instance of the ServerSocket reference above. The object is then set to listen on port 9999
    System.out.println("Server waiting for client connection...");
    }

    catch (IOException e) //the ServerSocket object throws an exception if it cannot listen on the specified port i.e. if the port is being used for another service
    {
    System.err.println("Unable to listen on port: 9999.");
    System.exit(1);
    }

    //accepting a connection from a client

    while (listening) //a while loop is used to put the ServerSocket in an indefinite listening state

    try
    {
    //System.out.println("Server waiting for client connection...");
    clientSocket = ss.accept();
    System.out.println( "Connection established");
    System.out.println("Server waiting for client login request...");
    Server_thread sthread = new Server_thread(clientSocket);
    clients.add(sthread); //the newly connected client is then added to the vector to maintain a current list of connected clients
    sthread.start(); //in order to handle mutliple clients, a thread object is created and assigned to each client. This is how each client will communicate with server.

    }

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

    }
    }



    Server_thread.java

    import java.net.*;
    import java.io.*;
    import java.util.*;
    import java.util.logging.Level;
    import java.util.logging.Logger;

    public class Server_thread extends Thread
    {
    Socket clientSocket; //creates a reference to a Socket object
    Socket sock;
    String nick_name; //creates a reference toa string object. This will be used to store the nick name tha the client selects
    PrintWriter msg_out; //I/O //creates a reference to a printwriter object. This will handle the output
    Scanner msg_in; //creates a reference to a scanner object. This will handle the input
    public static Boolean connect_status; //creates a reference to a boolean object


    Server_thread(Socket sock) //constructor method passes a Socket object parameter

    {
    super("Server_thread"); //calls the constructor method for the super class
    connect_status= false; //sets the connect_status object to false therefore requiring the client to register
    nick_name = "";
    clientSocket = sock;

    try
    {
    //sindesi I/O antikeimenwn me ta streams tou socket
    msg_out = new PrintWriter(clientSocket.getOutputStream(), true);
    msg_in = new Scanner (clientSocket.getInputStream());
    }
    catch (Exception e)
    {
    System.out.println(e);
    }
    }

    synchronized void send(String msg)
    {
    msg_out.println(msg);
    }

    //setting up communication betweek the server and the client

    void begin()
    {

    //start the conversation with the client using the established protocols as specified in the Protocol class


    //Protocol prot = new Protocol(); //a new instance of the protocol class is created. This specifies the format and sequence of the messages that will be sent between the client and server
    //output = prot.processInput(null); //client communication from the server is initiated here. This is done by writing to the socket
    //msg_out.println(output);

    //while ((input = msg_in.nextLine()) != null) //performs communication with client by writing to the socket and reading from it

    //while ((msg_in.nextLine()) != null)
    try
    {
    //msg_in = new Scanner (clientSocket.getInputStream()); //gets the socket's input stream
    //msg_out = new PrintWriter(clientSocket.getOutputStream(), true); //gets the socket's output stream

    while (true)
    {
    String message = msg_in.nextLine(); //reads the input from the client
    System.out.println(message);
    //send(message);
    if (message.startsWith("Login")) //if the client's message starts with login, the register method is called
    {
    register(message);
    }

    else
    {
    msg_in.close();
    msg_out.close();
    sock.close();
    System.exit(1);
    }

    }

    }

    catch (IOException e)
    {
    e.printStackTrace();
    }


    }



    public void run()
    {
    begin();
    }

    //method that is used to register a new client requesting to join the network
    boolean register(String msg)
    {

    if (connect_status) //if the client is already registered, the message below is displayed
    {
    msg_out.println("You are already connected!");
    return true;
    }

    boolean exists = false;
    //System.out.println("Login" + msg.substring(5, msg.length())); //the substring method is called to reduce the message sent to omit the 'Login' part and simply display the user's desired nick name

    //the server checks through the clients list vector using a loop.
    //for each index in the vector, the connected client nick name is obtained by calling the get() method
    //a temporary thread is then created and the connected client object is assigned to it
    //the nick name of the temporary thread is then checked against the requested nick name.
    //if they are the same, then it means the new client's desired nick name is already in use
    //a break occurs and the server displays a new message requesting the user to select a different nick name

    for (int i = 0;i < Server.clients.size();i++)
    {
    if (Server.clients.get(i) != null)
    {
    //System.out.println(msg.substring(7, msg.length()));
    //System.out.println(msg);
    Server_thread temp_thread = (Server_thread)Server.clients.get(i);

    if ((temp_thread.nick_name).equals(msg.substring(7, msg.length())))
    {
    exists = true;
    break;
    }

    }
    }

    if (exists)
    {
    msg_out.println("Choose a different nick name");
    }

    //however, if the temprorary thread object's nick name variable does not match the desired nick name
    //the connection status is set to 'true' and the client's nick name is registered with the server
    //the server then creates an instance of the ListClients class and calls the List() method on it
    //in order to produce an updated list of currently connected clients and output the list to the client

    else
    {
    connect_status = true;
    nick_name = msg.substring(7,msg.length());
    ListClients lc = new ListClients();
    lc.List();
    //System.out.println(lc.client_list);
    System.out.println("New client " + nick_name + " has been successfuly registered to server");
    //ListenerThread listener = new ListenerThread(clientSocket, nick_name);
    //Thread lst = new Thread(nick_name);
    //lst.listen();
    //lst.start();
    //listen();


    // for (int i = 0;i < Server.clients.size();i++)
    //{
    //if (Server.clients.get(i) != null)
    // {
    int i = Server.clients.indexOf(this);
    Server_thread temp_thread = (Server_thread)Server.clients.get(i);
    System.out.println("Wating for messages...");
    temp_thread.listen();

    //System.out.println(lst);

    // }

    //}

    }

    return true;

    }

    //class ListenerThread extends Thread

    // Socket clientSocket;
    // Scanner str_in;
    // boolean listen = true;
    // String nick_name;

    // ListenerThread(Socket clientSocket, String nick_name)
    // {
    // this.clientSocket = Server_thread.clientSocket;
    // this.nick_name = Server_thread.nick_name;//boolean sendAll(String msg)

    // }


    public boolean listen()
    {
    boolean listening = true;

    try
    {
    msg_in = new Scanner (clientSocket.getInputStream());
    msg_out = new PrintWriter(clientSocket.getOutputStream(), true);
    }
    catch(Exception e)
    {
    System.out.println("Unable to get unput stream");
    }

    while (listening = true)

    if (Server_thread.connect_status = true)
    {
    String str = msg_in.nextLine();
    //String message;
    if (str.startsWith("Post"))
    {
    //sendAll(message);
    //System.out.println(str.substring(5, str.length()));
    //int i = Server.clients.indexOf(this);
    //Server_thread tt = (Server_thread)Server.clients.get(i);
    send("Recieve "+ nick_name+": " +str.substring(5, str.length()));
    System.out.println(str);

    //send("Recieve "+ nick_name+": " +str.substring(5, str.length()));
    //System.exit(1);
    //str = null;
    listening = true;

    }
    //return;
    }

    return listening;



    }





    }


    Client.java

    import java.net.*;
    import java.io.*;
    import java.util.*;
    import java.util.logging.Level;
    import java.util.logging.Logger;

    public class Client
    {

    public static void main(String[] args) throws IOException {
    //public void run()
    {
    Socket sock = null;
    PrintWriter msg_out = null;
    Scanner msg_in = null;
    String hostname = null;

    try {

    Scanner host_pc = new Scanner(System.in);
    //msg_in = new Scanner (sock.getInputStream());
    //msg_in = new Scanner (System.in);
    System.out.print("\n\nEnter host name: ");
    hostname = host_pc.nextLine();
    //hostname = msg_in.nextLine();
    sock= new Socket(hostname, 9999);
    msg_out = new PrintWriter(sock.getOutputStream(), true);
    msg_in = new Scanner (sock.getInputStream());
    System.out.print("\n\nSelect a nick name: ");

    }
    catch (UnknownHostException e)
    {
    System.err.println("Error! Could not connect to host: " + hostname);
    //System.exit(1);
    return;

    }
    catch (IOException e)
    {
    System.err.println("Error! Could not get the input and output streams for the connection to: " + hostname);

    System.exit(1);
    }
    // Send some data to the server.

    //System.out.println("\n\nEnter message: ");
    //String toServer = "Are you there, Server?";
    //msg_out.write(toServer);
    //msg_out.newLine();
    //msg_out.flush();

    // Wait for a response from the server and display it.

    Scanner input = new Scanner(System.in);

    String userInput;

    while ((userInput = input.nextLine()) != null)
    {



    //System.exit(1);
    msg_out.println(userInput);
    System.out.println(msg_in.nextLine());
    // Use a BufferedReader to read data from the server.
    //input = new Scanner (sock.getInputStream());
    //String fromServer = msg_in.nextLine();
    //System.out.println("FromServer: " + fromServer);
    //String fromServer = msg_in.nextLine();
    //System.out.println("FromServer: " + fromServer);
    }

    msg_out.close();
    msg_in.close();
    input.close();
    try {
    sock.close();
    } catch (IOException ex) {
    Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
    }
    }

    }
    }

  2. #2
    Join Date
    Apr 2007
    Posts
    425

    Re: Chat application problem

    paste them with code formatting.
    ------
    If you are satisfied with the responses, add to the user's rep!

  3. #3
    Join Date
    Dec 2009
    Posts
    5

    Re: Chat application problem

    how do i do that?

  4. #4
    Join Date
    Feb 2008
    Posts
    966

    Re: Chat application problem

    Try reading the "Before you Post..." section.

  5. #5
    Join Date
    Jul 2005
    Location
    Currently in Mexico City
    Posts
    566

    Re: Chat application problem

    use [code] tags
    if code is big to fit in a pair of screens better attach it as a file
    Wanna install linux on a vacuum cleaner. Could anyone tell me which distro sucks better?

    I had a nightmare last night. I was dreaming that Iím 64-bit and my blanket is 32-bit and I couldnít cover myself with it, so Iíve spent the whole night freezing. And in the morning I find that my blanket just had fallen off the bed. =S (from: bash.org.ru)

    //always looking for job opportunities in AU/NZ/US/CA/Europe :P
    willCodeForFood(Arrays.asList("Java","PHP","C++","bash","Assembler","XML","XHTML","CSS","JS","PL/SQL"));

    USE [code] TAGS! Read this FAQ if you are new here. If this post was helpful, please rate it!

  6. #6
    dlorde is offline Elite Member Power Poster
    Join Date
    Aug 1999
    Location
    UK
    Posts
    10,163

    Re: Chat application problem

    Quote Originally Posted by ProgramThis View Post
    Try reading the "Before you Post..." section.
    Unfortunately, it's not easy to find any more, even if you know it exists...

    The greatest obstacle to discovery is not ignorance, but the illusion of knowledge...
    D. Boorstin
    Please use &#91;CODE]...your code here...&#91;/CODE] tags when posting code. If you get an error, please post the full error message and stack trace, if present.

  7. #7
    Join Date
    Dec 2009
    Posts
    5

    Re: Chat application problem

    Thanks for your prompt responses guys. I really appreciate it. Now I managed to solve the first problem but now I have a different problem. THe problem I have now is this:

    When a client connects to the server, the server sends a login request via the printwriter. On the clients screen, this is displayed as 'Login:'. The client must then enter 'Login: ' followed by the desired nick name. Once the client does this, the server will check if there is already a user with that nick name. If not, then the user is added to the vector clients and a new thread is started. Now after the user is successfully logged in, the listen)message(0 method is called to listen for new messages. To send a message, the Client must then type 'Post ' followed by the message. This message is then sent to all users that are currently connected.

    The problem I am facing is that when the client tries to send a message, when it is the only client connected, the message is send succesfully but then it cannot send any more messages until it receives a message from the server or another client. It is as if the client must receive a message before it can send. Now when, you have two clients connected, and client A sends a message, client B receives the message and then client A is unable to send any more messages until client b sends a message of its own.

    I want the client to be able to send a message without having received one. For example if only one client is connected, I want that client to be able to send messages as many times as it wants even if it is not receiving any messages.
    With regards to two connected clients, I want client A to be able to send a message to client B without having to receive a message from client B. I want simultaneous sending and receivng. Is this possible? So far i think the problem is with the BufferedReader and the Printwriter but I can't figure out exactly what it is. I have attached the files to this thread. i would really appreciate it if someone could help me with this before the weekend runs out. Thanks in advance guys
    Attached Files Attached Files

  8. #8
    Join Date
    May 2006
    Location
    UK
    Posts
    4,474

    Re: Chat application problem

    When posting code please don't post code which is full of commented out lines as it makes it difficult to read. Also adding some comments explaining what sections of code are supposed to do would help.

    Your problem is in the client which writes the users input text and then reads from the socket stream twice before allowing the user to enter more text.

    If the client does not receive 2 messages from the server it will block. There are fews ways around this such as having separate threads for writing and reading.

  9. #9
    Join Date
    Dec 2009
    Posts
    5

    Re: Chat application problem

    Thank you very much keang. Sorry about the commented out lines and sorry that it was difficult for you to read the code. I suspected that the problem was with the client. Now I changed it so that it reads from the socket stream only once. but it still does not work properly. In this case, the client has to wait for a message to be received before it can send one. What I want is for the client to be able to send messages at anytime i.e. the client does not have to receive a message before it can send one. Also, the client should be able to receive messages without having to send one. Can you tell me how to do this? If you could just give me an example of how to do this I would really appreciate it, like maybe a few lines of code that I can add to get it working. I am really interested in doing it by using separate threads for reading and writing but I am cautious. Now if I do decide to use separate threads for reading and writing, does that mean each client will be attached to 2 threads?

  10. #10
    Join Date
    May 2006
    Location
    UK
    Posts
    4,474

    Re: Chat application problem

    The best way to do this is using 2 threads but if that is beyond your skill and you just want to get something working you could try using the BufferredReaders ready() method to check if there is anything to read before actually calling read(). This will prevent your code blocking whilst waiting for a message.

    You will have to repeatedly poll both your keyboard input stream and the socket input stream to give reasonable responsiveness and you will have to put some sleep(..) or wait(..) calls or you'll end up using 100% of the processor resource and typing will become really unresponsive.

    Note: I've never tried this and don't know how robust a solution this will be.

  11. #11
    Join Date
    Dec 2009
    Posts
    5

    Re: Chat application problem

    Ok, do you know where I can get more info on this?

  12. #12
    Join Date
    May 2006
    Location
    UK
    Posts
    4,474

    Re: Chat application problem

    Ok, do you know where I can get more info on this?
    On what. Do you mean on using threads or on the bodge solution I outlined?

    On the former you could try google and the later try reading the Java API Docs.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center