Search code examples
javaclientchatobjectinputstream

Creating a client-server chat program


In a server client chat program using object streams how would i be able to send a message to all clients and a private msg to certain clients?

in my listening for connections method i accept the connection

public void listenForConnections()
{
    String sUserName="";

    try{
        do {
            System.out.println("Waiting on connections");
            Socket client = servSocket.accept();
            System.out.println("Connection From: " + client.getInetAddress());          


            //pass message handling to thread and listen
            ClientHandler handler = new ClientHandler(client,this);
            handler.start();//As usual, this method calls run.                

        } while (true);
    }
    catch(Exception e){
        e.printStackTrace();
    }
}

Then i pass this client to a thread in the server to handle message exhanges;

i,e;

            //pass message handling to thread and listen
            ClientHandler handler = new ClientHandler(client,this);
            handler.start();//As usual, this method calls run.

How and where do i keep a list of connected clients?

i thought of a hastable with the key being the username and ObjectOutPutStream. And to then read object being sent after the connection was accepted but i ran into problems. The message was a login command giving the username and a command LOGIN

My code became;

System.out.println("Waiting on connections"); Socket client = servSocket.accept(); System.out.println("Connection From: " + client.getInetAddress());

            ObjectOutputStream clientOOS = new ObjectOutputStream(client.getOutputStream());

            outputStreams.put(sUserName, oos );


            //big problem here
            //serializeation
            /*ois = new ObjectInputStream(client.getInputStream());
            oos = new ObjectOutputStream(client.getOutputStream());

            //ask for the username /authenticate
            System.out.println("SERVER: getting username");
            myMessage inMessageLogin = (myMessage) ois.readObject();

            if(inMessageLogin.getCOMMAND()==ServerCommands.CMD_LOGIN)
            {
                sUserName=inMessageLogin.getsUserName();
                System.out.println("SERVED User " + sUserName + " connected.");
                //save stream
                outputStreams.put(sUserName, oos );
                //oos.close();
                //oos.flush();
                //ois.close();
                ois=null;
                //oos=null;
            }
            //end of problem!!!!!*/

Which i commented out as it gave errors about corrupted streams, any ideas?

Thanks

To send a message to the server from client;

//default cmd is to send to all
public void sendMessage(String sText,int iCommand)
{
    System.out.println("sendMessage");

    outMessage=new myMessage();

    outMessage.setsUserName(sCurrentUser);
    //set command
    outMessage.setCOMMAND(iCommand);

    outMessage.setsMessage(sText);

    System.out.println("send msg" + outMessage.displayMessage());

    try {
        oos.writeObject(outMessage);
        oos.flush();
        oos.reset();
        //clear up send message from txbox
        txtMessage.setText("");
    } catch (IOException ex) {
        Logger.getLogger(myClientGUI.class.getName()).log(Level.SEVERE, null,

ex); } }

client code to connect to server;

public void connectToServer()
{
    String sServer=txtServer.getText();
    PORT=Integer.parseInt(txtPort.getText());
    try {
        //host = InetAddress.getByName("localhost");//InetAddress.getLocalHost();
        host = InetAddress.getByName(sServer);
        clientSocket = new Socket(host, PORT);
    }
    catch (Exception e){
        e.printStackTrace();
    }
}

public boolean createStreams()
{
    try{
        //serial
        //*******************************************************************************
        // open I/O streams for objects - serialization streams
        oos = new ObjectOutputStream(clientSocket.getOutputStream());
        ois = new ObjectInputStream(clientSocket.getInputStream());



        return true;
    }
    catch(Exception e)
    {
        e.printStackTrace();
        return false;
    }
}

Solution

  • Following code works perfectly well for me. Note that Server class must have access to Message class in it's classpath and that Message class implements Serializable.

    Client:

    class Client {
        private Socket clientSocket;
    
        public void connectToServer()
        {
            String sServer="localhost";
            int PORT = 8181;
            try {
                InetAddress host = InetAddress.getByName(sServer);
                clientSocket = new Socket(host, PORT);
            }
            catch (Exception e){
                e.printStackTrace();
            }
        }
    
        public void sendMessage(String sText,int iCommand) throws IOException {
            Message outMessage = new Message();
    
            outMessage.setCOMMAND(iCommand);
            outMessage.setsMessage(sText);
    
            ObjectOutputStream oos = new ObjectOutputStream(clientSocket.getOutputStream());
            try {
                oos.writeObject(outMessage);
                oos.flush();
                oos.reset();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    
        public static void main(String[] args) {
            Client c = new Client();
            c.connectToServer();
            try {
                c.sendMessage("test message", 42);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    class Message implements Serializable {
        private int iCommand;
        private String sText;
    
        public void setCOMMAND(int iCommand) {
            this.iCommand = iCommand;
        }
    
        public void setsMessage(String sText) {
            this.sText = sText;
        }
    
        @Override
        public String toString() {
            return "Message{" +
                    "iCommand=" + iCommand +
                    ", sText='" + sText + '\'' +
                    '}';
        }
    }
    

    Server:

    class Server {
        public static void main(String[] args) throws IOException {
            ServerSocket serverSocket = new ServerSocket(8181);
    
            do {
                Socket s = serverSocket.accept();
                try {
                    processClient(s);
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            } while (true);
        }
    
        private static void processClient(Socket s) throws IOException, ClassNotFoundException {
            ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
            Message message = (Message) ois.readObject();
            System.out.println(message.toString());
        }
    }