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.