Multithreaded Chat Server/Client
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 3 of 3

Thread: Multithreaded Chat Server/Client

  1. #1
    Join Date
    Mar 2009
    Posts
    22

    Multithreaded Chat Server/Client

    I feel I may have horribly screwed this one up, and I'm again looking for some insight in to my mistakes. I'm supposed to write a multi-threaded chat server/client program that the server accepts requests and (messages) and sends them to the appropriate clients. The problem I'm having currently is that my client threads won't seem to stay connected. They do connect to begin with, then immediate disconnect and an error is thrown. Here's my code:

    ChatClientThread Class:
    Code:
    package chatroom;
    
    import java.io.IOException;
    import java.net.Socket;
    import java.util.Scanner;
    
    /**
     *
     */
    public class ChatClientThread extends Thread
    {
        private Socket socket;
        private ChatClient client;
        private Scanner in;
    
        public ChatClientThread(ChatClient c, Socket s)
        {
            client = c;
            socket = s;
            open();
            start();
        }
    
        public void open()
        {
            try
            {
                in = new Scanner(socket.getInputStream());
            }
            catch (IOException ex)
            {
                System.out.println("Error Getting Input Stream: " + ex);
                ex.printStackTrace();
            }
        }
    
        public void close()
        {
            if (in != null) in.close();
        }
    
        public void run()
        {
            while(true)
            {
                client.handle(in.nextLine());
            }
        }
    }
    ChatClient Class:
    Code:
    package chatroom;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.net.Socket;
    import java.net.UnknownHostException;
    import java.util.Scanner;
    
    /**
     *
     */
    public class ChatClient implements Runnable
    {
        private Socket socket;
        private Thread thread;
        private Scanner in;
        private PrintWriter output;
        private ChatClientThread client;
    
        public ChatClient(String hostname, int port)
        {
            try
            {
                System.out.println("Connecting, please wait...");
                socket = new Socket(hostname, port);
                System.out.println("Connected: " + socket);
            }
            catch (UnknownHostException ex)
            {
                System.out.println("Unknown Host: " + ex.getMessage());
                ex.printStackTrace();
            }
            catch (IOException ex)
            {
                System.out.println("I/O Exception: " + ex.getMessage());
                ex.printStackTrace();
            }
        }
    
        public void run()
        {
            while(thread != null)
            {
                output.println(in.nextLine());
            }
        }
    
        public void handle(String msg)
        {
            if(msg.equals(".exit"))
            {
                System.out.println("Exiting. Press RETURN.");
                stop();
                System.exit(0);
            }
        }
    
        public void start() throws IOException
        {
            in = new Scanner(System.in);
            output = new PrintWriter(socket.getOutputStream(), true);
    
            if(thread == null)
            {
                client = new ChatClientThread(this, socket);
                thread = new Thread(this);
                thread.start();
            }
        }
    
        public void stop()
        {
            try
            {
                if (thread != null) thread = null;
                if (in != null) in.close();
                if (output != null) output.close();
                if (socket != null) socket.close();
            }
            catch (IOException ex)
            {
                System.out.println("Error in closing");
                ex.printStackTrace();
            }
        }
    
        public static void main(String args[])
        {
            ChatClient client = new ChatClient("localhost", 5678);
        }
    }
    ChatServerThread Class:
    Code:
    package chatroom;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.net.Socket;
    import java.util.Scanner;
    
    /**
     *
     */
    public class ChatServerThread extends Thread
    {
        private ChatServer server;
        private Socket socket;
        private int ID = -1;
        private Scanner input;
        private PrintWriter output;
    
        public ChatServerThread(ChatServer serv, Socket sock)
        {
            super();
            server = serv;
            socket = sock;
            ID = socket.getPort();
        }
    
        public void send(String msg) {output.println(msg);}
    
        public int getID() {return ID;}
    
        public void run()
        {
            System.out.println("server Thread " + ID + " is running");
            String msg = null;
            while((msg = input.nextLine()) != null)
                server.handle(ID, msg);
        }
    
        public void open() throws IOException
        {
            input = new Scanner(socket.getInputStream());
            output = new PrintWriter(socket.getOutputStream());
        }
    
        public void close() throws IOException
        {
            if (socket != null) socket.close();
            if (input != null) input.close();
            if (output != null) output.close();
        }
    }
    ChatServer Class:
    Code:
    package chatroom;
    
    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    /**
     *
     */
    public class ChatServer implements Runnable
    {
        private ChatServerThread clients[] = new ChatServerThread[50];
        private ServerSocket server;
        private Thread thread;
        private int clientCount = 0;
    
        public ChatServer(int port)
        {
            try
            {
                System.out.println("Connecting to port " + port + ".");
                server = new ServerSocket(port);
                System.out.println("Server Started: " + server);
                start();
            }
            catch (IOException ex)
            {
                System.out.println("Unable to connect to port " + port + ex.getMessage());
                ex.printStackTrace();
            }
        }
    
        public void start()
        {
            if (thread == null)
            {
                thread = new Thread(this);
                thread.start();
            }
        }
    
        public void stop()
        {
            if (thread != null)
                thread = null;
        }
    
        public void run()
        {
            while(thread != null)
            {
                try
                {
                    System.out.println("Waiting to client");
                    addThread(server.accept());
                }
                catch (IOException ex)
                {
                    System.out.println("Server accept error: " + ex);
                    ex.printStackTrace();
                    stop();
                }
            }
        }
    
        private int findClient(int ID)
        {
            for(int i = 0; i < clientCount; i++)
                if(clients[i].getID() == ID)
                    return i;
            return -1;
        }
    
        public synchronized void handle(int ID, String input)
        {
            if (input.equals(".exit"))
            {
                clients[findClient(ID)].send(".exit");
            }
    
            else
                for(int i = 0; i < clientCount; i++)
                    clients[i].send(ID + ": " + input);
        }
    
        public synchronized void remove(int ID)
        {
            int pos = findClient(ID);
            if(pos >= 0)
            {
                ChatServerThread toDie = clients[pos];
                System.out.println("Removing Client Thread " + ID + " at " + pos);
    
                if(pos < clientCount - 1)
                {
                    for(int i = pos + 1; i < clientCount; i++)
                       clients[i-1] = clients[i];
    
                    clientCount--;
                }
    
                try
                {
                    toDie.close();
                }
                catch(IOException ex)
                {
                    System.out.println("Error Closing Thread: " + ex);
                    ex.printStackTrace();
                    toDie.stop();
                }
            }
        }
    
        private void addThread(Socket socket)
        {
            if(clientCount < clients.length)
            {
                System.out.println("Client Accepted: " + socket);
                clients[clientCount] = new ChatServerThread(this, socket);
    
                try
                {
                    clients[clientCount].open();
                    clients[clientCount].start();
                    clientCount++;
                }
                catch(IOException ex)
                {
                    System.out.println("Error Opening Thread: " + ex);
                    ex.printStackTrace();
                }
            }
    
            else
                System.out.println("Client Refused: maximum of " + clients.length + " reached");
        }
    
        public static void main(String args[])
        {
            ChatServer server = new ChatServer(5678);
        }
    }
    The Error I get is:
    Code:
    /*Correctly Echoed Commands Here*/
    Connecting to port 5678.
    Server Started: ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=5678]
    Waiting to client
    Client Accepted: Socket[addr=/127.0.0.1,port=46956,localport=5678]
    Waiting to client
    server Thread 46956 is running
    
    /*Error is Here*/
    Exception in thread "Thread-1" java.util.NoSuchElementException: No line found
            at java.util.Scanner.nextLine(Scanner.java:1516)
            at chatroom.ChatServerThread.run(ChatServerThread.java:36)
    The ChatServer class will continue to run and accept clients, so I'm pretty sure I got that right. What I seem to have screwed up, based on the error messages is to make the client lay in wait for the user to type something as a message. Instead of laying in wait, it simply exits based on (I think) the above error. I'm just not sure how to fix it.

    Any suggestions and/or pointers would be greatly appreciated, as always.

    Thanks!

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

    Re: Multithreaded Chat Server/Client

    Read the API docs for the methods you are using. The Scanners nextLine() method throws a NoSuchElementException if there is no line available.

    You can't just blindly call nextLine() in the hope of there being data, but if you read the docs you will see there is a hasNextLine() method which returns true if there is a line of data.
    Posting code? Use code tags like this: [code]...Your code here...[/code]
    Click here for examples of Java Code

  3. #3
    Join Date
    Apr 2010
    Posts
    11

    Re: Multithreaded Chat Server/Client

    Dear Sir: In ChatServerThread, you need to flush the output buffer. Ex:
    output = new PrintWriter(socket.getOutputStream(),true); // autoflush = true

    You can verify that you are receiving data by putting a System.out.println in your send() method.
    If you run ChatServer and open a telnet session from a command line window:
    C:\>telnet localhost 5678, you can test your input / output streams. You can put a message like this in the open() method: output.println("Enter Exit to escape"); This ought to show up in the telnet session at its start.

    I don't know about the other two programs. Good luck.

Posting Permissions

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


Azure Activities Information Page

Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center