0

iam working on a instant messaging software and was stuck on this problem, i am using hashmap to store ObjectOutputStream in Hash map with the name of the user as key, and use the ObjectOutputStream object stored in the hashmap to redirect the message using the username as key, here is the code

package com.chatting.server;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class Server extends JFrame {

/**
 * @param args
 */
private JTextField texts;
private JTextArea area;
private ObjectOutputStream output;
private ObjectInputStream input;
private ServerSocket server;
private Socket connection;
private ArrayList<Socket> clientlist;
private int index;
private String[] fwdMessage;
private ObjectOutputStream forward;
public Map<String, ObjectOutputStream> selectClient; 
public String stringParts[];
public String fwdMssgSend, from;
public Server(){
    super("server appliction");
    clientlist = new ArrayList<Socket>();
    texts = new JTextField();
    area = new JTextArea();
    selectClient = new HashMap<String, ObjectOutputStream>();
    stringParts = null;
    texts.addActionListener(
            new ActionListener(){
                public void actionPerformed(ActionEvent eve){
                    //sendMessage(eve.getActionCommand());
                    //texts.setText("");
                }
            }
    );
    add(texts, BorderLayout.NORTH);
    texts.setEditable(false);
    add(new JScrollPane(area));
    setSize(300,250);
    setVisible(true);
    try {
        //dbConnection();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }//connects to the database
}
public void startServer(){
    try{
        server = new ServerSocket(1234, 100);

            try{
                while(true){
                    waitForConnection();
                    Thread t1 = new Thread(){

                        public void run() {
                            setUpStreams();
                            try {
                                    whileChattingServer();
                            } catch (Exception e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        }

                    };
                    t1.start();
                }
            }
            catch(Exception exec){
                exec.printStackTrace();
            }
            finally{
                try {
                    CloseChat();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        //t1.setDaemon(true);
    }
    catch(Exception excpt){
        excpt.printStackTrace(); 
    }
}
//waits for connections
public  void waitForConnection(){
    try{
        showMessage("waiting for connection");
        connection = server.accept();//accepts the connection from the client 
        //String in = index.toString();
        showMessage("connection was successful with");
    }
    catch(Exception ex){
        ex.printStackTrace();
    }
}
//sending and recieving of data
public  void setUpStreams(){
    try{
        output = new ObjectOutputStream(connection.getOutputStream());
        output.flush();
        input = new ObjectInputStream(connection.getInputStream());//will need to remove this and keep it in the sendmessage method to forward message to selected client
        showMessage("\n stream setting completed \n");
    }
    catch(Exception exst){
        exst.printStackTrace();
    }
}
// get the message and sends the message while chatting
public  void whileChattingServer() throws IOException {
    if(forward != null){
        sendMessage("You are connected", forward);
    }
    texts.setEditable(true);
        String message="";
            while(true){
                try{
                    //if(input == null){
                        //input = new ObjectInputStream(connection.getInputStream());
                    //}
                    message = (String) input.readObject();
                    System.out.println("THE RAW MESSAGE IS"+message);
                    showMessage(message);
                    stringParts = message.split("-");
                    showMessage("selected mode is"+stringParts[0]);
                    if(stringParts[0].equals("login")){
                        boolean chicks = loginCheck(stringParts[1], stringParts[2]);        
                        if(chicks){
                            addclients(stringParts[1], output);//add socket connections that the client made to the array list
                        }
                        else{
                            area.append("\n The User cannot enter because he does not exist in the database");
                        }
                    }
                    else{
                        if(selectClient.get(stringParts[0]) != null){
                            area.append("\n \n Forwarding the message from "+stringParts[1]+" to "+stringParts[0]);
                            area.append("\nThe number of user logged ins is "+selectClient.size());
                            forward=(ObjectOutputStream) selectClient.get(stringParts[0]);
                        }
                        else{
                            area.append("\n The selected user is not logged in");
                            forward=null;
                        }
                        System.out.println("forwarding to "+stringParts[0]);
                        if(forward != null){ /* IMPORTANT: THE MESSAGE SENT WILL CONTAIN THE FOLLOWING ---->
                        THE FIRST ELEMENT (0) WILL BE THE RECEIVER NAME, THE SECOND ELEMENT (1) WILL CONTAIN THE SENDER NAME  THE THIRD WILL CONTAIN THE MESSAGE
                        */
                            System.out.println("receiver socket is not null");
                            from=stringParts[1];//this name will be displayed to the receiver
                            int arrLength=stringParts.length;
                            fwdMessage = new String[arrLength-2];
                            fwdMessage = Arrays.copyOfRange(stringParts, 2, arrLength);
                            fwdMssgSend= Arrays.toString(fwdMessage);
                            sendMessage(from+"==>"+fwdMssgSend, forward);
                            fwdMssgSend="";
                        }
                        else{
                            area.append("\n Sending Failed because the selected reciever is not logged in");
                        }
                    }
                }
                catch(Exception blah){
                    blah.printStackTrace();
                    showMessage("Cannot read the sent message");

                }
            }
    //t2.setDaemon(true);
}
public void CloseChat() throws IOException{
    output.close();
    texts.setEditable(false);
    connection.close();
}
public void sendMessage(String message, ObjectOutputStream dest){ //sends the message to the client pass object to choose where to send the message
    try{
        if(dest != null){
            //output = new ObjectOutputStream(dest.getOutputStream());//previously it was "connection" instead of "clientlist"..sends the message to clients
            System.out.println("destination selected");
            System.out.println("message to send= "+message);
            //output.writeObject(message);
            dest.writeObject(message);
            showMessage(message);
        }
        else{
            output.writeObject(message);
            showMessage(message);
        }
        //output.writeObject(message);
        output.flush();
        //showMessage(message);
    }
    catch(Exception exx){
        area.append("\n cannot send the message \n");
    }
}
//post the messages
public void showMessage(final String mssgs){
    SwingUtilities.invokeLater(new Runnable(){
        public void run(){
            area.append("\n"+mssgs);
        }
    });
}

public void addclients(String user, ObjectOutputStream conns){
    //clientlist.add(conns);//stores the connections of different clients
//  index=clientlist.indexOf(conns);
    if(selectClient.get(user) == null){
        area.append("\n Inside the method to add client");
        selectClient.put(user, conns);
        area.append("\n The number of user logged in are "+ selectClient.size());
    }
    area.append("\n"+index);
}
// connects to the database to retrieve name and password of the user
public boolean loginCheck(String name, String password) throws Exception{
    //String res="";
    area.append("\n INSIDE LOGINCHECK.........");
    area.append("\n user name is "+name+" and password is "+password);
    forward=(ObjectOutputStream) selectClient.get(name);
    Class.forName("com.mysql.jdbc.Driver");
    Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/javachat","root", "honghonoh");
    PreparedStatement ps = conn.prepareStatement("select * from logintable where name = ? and password = ? ");
    ps.setString(1, name);
    ps.setString(2, password);
    ps.addBatch();
    showMessage("\n after prepared statement");
    ResultSet result = ps.executeQuery();
    if(!result.next()){
        //Boolean logincheck=false;
        //output.writeObject(logincheck);
        sendMessage("falseFromServer-TryAgainNextTimr", forward);
        area.append("\n match NOT found");
        return false;
    }
    else{
        //Boolean logincheck=true;
        //output.writeObject(logincheck);
        ps = conn.prepareStatement("select * from logintable");
        result = ps.executeQuery();
        int i=0;
        String returnall=null;
        //selectClient.put(name, clientlist.get(index));
        while(result.next()){
            if(i==0){
                returnall=result.getString(2);
            }
            else{
                returnall=returnall+"-"+result.getString(2);
            }
            i++;
        }
        sendMessage("trueFromServer-"+returnall, forward);
        area.append("\n match found");
        return true;
    }
    //area.append("\n"+res);
}

}

The problem is when two user log in and start chatting the user who log in last can send the message and the other can receive the message, but when the user who log in first can send the message only once and the program just refuses to send the message after that, and the error i received is

at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at com.chatting.server.Server.whileChattingServer(Server.java:151)
at com.chatting.server.Server$2.run(Server.java:87)
java.io.StreamCorruptedException: invalid type code: 00

Also, is it a good idea to use ObjectOutputStream as a redirect mechanism?, is there a better way to do it, if so please tell me. This is driving me crazy, also please note that i am beginner in java swing and socket programming, thank you.

  • I managed to solve the problem by using hash-map to store the ObjectInputStream object for each user who logged in and then call the appropriate object using the username – user2735469 May 05 '14 at 13:06
  • Duplicate of [StreamCorruptedException: invalid type code: AC](http://stackoverflow.com/questions/2393179/streamcorruptedexception-invalid-type-code-ac) – user207421 May 09 '14 at 05:51
  • In other words you were previously using multiple `ObjectInputStreams` per socket. See the duplicate for why this is wrong. – user207421 May 09 '14 at 05:51
  • @EJP yeah i tried the reset() method before. the problem still persists. am i doing something wrong here? I know i am duct-taping it but i don't know what else to do – user2735469 May 15 '14 at 05:23
  • begining to feel that this question is like a plague :) – user2735469 May 27 '14 at 10:34
  • NVM fixed the problem after some serious ductaping. – user2735469 Feb 08 '15 at 14:57

0 Answers0