1

I'm new to socket programming in Java and I'm trying to create a simple chat between 2 clients through a server. The server will receive message from this client and send to the other. Server

public class ServerV2 extends JFrame {
/**
 * 
 */
private static final long serialVersionUID = -1958631621285336523L;
private ServerSocket serverSocket;
private ObjectOutputStream outputStream;
private int port;
private ArrayList<ClientHandler> clients = new ArrayList<ClientHandler>();

private JTextArea messageBox;

private void initializeUI() {
messageBox = new JTextArea();

add(new JScrollPane(messageBox), BorderLayout.CENTER);
setTitle("Server");
setSize(256, 256);

setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}

public ServerV2(int port) {
this.port = port;
initializeUI();
}

public void startServer() {
try {
    serverSocket = new ServerSocket(port, 100);
    while (true) {
    try {
        Socket clientSocket = serverSocket.accept();
        ClientHandler client = new ClientHandler(this, clientSocket);
        clients.add(client);
        client.start();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
    }
    }
} catch (Exception e) {
    e.printStackTrace();
}
}

void sendMessage(String message, ClientHandler fromClient) {
try {
    for (ClientHandler clientHandler : clients) {
    if (!clientHandler.equals(fromClient)) {
        outputStream = new ObjectOutputStream(
            clientHandler.getClient().getOutputStream());
        outputStream.writeObject(message);
        outputStream.flush();
    }
    }
    showMessage(message, fromClient);
} catch (IOException e) {
    System.out.println("What the heck are you trying to send?");
}
}

void showMessage(String message, ClientHandler fromClient) {
SwingUtilities.invokeLater(new Runnable() {
    public void run() {
    messageBox.append("\n" + fromClient.getUserName() + " said "
        + message);
    }
});
}}

ClientHandler

public class ClientHandler extends Thread {
private ServerV2 server;
private Socket clientSocket;
private String userName;
private ObjectInputStream inputStream;
private String message;

public String getUserName() {
    return userName;
}

public Socket getClient() {
    return clientSocket;
}

public ClientHandler(ServerV2 server, Socket client) {
this.server = server;
try {
    inputStream = new ObjectInputStream(client.getInputStream());
} catch (IOException e) {
    e.printStackTrace();
}
this.clientSocket = client;
}

@Override
public void run() {
try {
    userName = (String)inputStream.readObject();
    readMessage();
} catch (Exception e) {
    e.printStackTrace();
}
}

private void readMessage() throws IOException {
do {
    try {
    message = (String)inputStream.readObject();
    server.sendMessage(message, this);
    } catch (ClassNotFoundException e) {

    }
} while (!message.equals("EXIT"));
}

@Override
public boolean equals(Object obj) {
    if (obj == null) return false;
    ClientHandler client = (ClientHandler)obj;
    if (this.userName.equals(client.getUserName())) return true;
    return false;
}}

Client

public class Client extends JFrame {
/**
 * 
 */
private static final long serialVersionUID = -3219203310153720970L;
private JTextField txtMessageInput;
private JTextArea messageBox;

private Socket clientSocket;
private String message;
private ObjectOutputStream outputStream;
private ObjectInputStream inputStream;
private String host;
private int port;
private String userName;

public String getUserName() {
    return userName;
}

public void setUserName(String userName) {
    this.userName = userName;
}

public Client(String host, int port, String userName) {
this.host = host;
this.port = port;
this.userName = userName;
initializeUI();
}

private void initializeUI() {
txtMessageInput = new JTextField();
txtMessageInput.addActionListener(new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent e) {
    sendMessage(e.getActionCommand());
    txtMessageInput.setText("");
    }
});

messageBox = new JTextArea();
add(txtMessageInput, BorderLayout.NORTH);
add(new JScrollPane(messageBox), BorderLayout.CENTER);
setTitle("Client");
setSize(256, 256);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}

public void startClient() {
try {
    System.out.println("Starting client with username " + userName);

    // Connect to server
    connectToServer();

    // Setup streams to send and receive data from server
    setupStreams();

    // send username to server
    outputStream.writeObject(userName);

    // read messages from server
    readMessage();
} catch (EOFException e) {
    System.out.println("You closed the connection.");
} catch (IOException e) {
    e.printStackTrace();
} finally {
    closeConnection();
}
}

private void connectToServer() {
System.out.println("Searching for server ...");
try {
    clientSocket = new Socket(InetAddress.getByName(host), port);
} catch (Exception e) {
    e.printStackTrace();
}
System.out.println("Connected to server.");
}

private void setupStreams() throws IOException {
System.out.println("Setup streams ...");
outputStream = new ObjectOutputStream(clientSocket.getOutputStream());
inputStream = new ObjectInputStream(clientSocket.getInputStream());
System.out.println("Streams are setup ...");
}

private void readMessage() throws IOException {
do {
    try {
    message = (String) inputStream.readObject();
    showMessages(message);
    } catch (ClassNotFoundException e) {
    System.out.println("Blah blah blah, I don't know this language ...");
    }
} while (!message.equals("EXIT"));
}

public void sendMessage(String message) {
try {
    outputStream.writeObject(message);
    outputStream.flush();
    showMessages(message);
} catch (IOException e) {
    System.out.println("What the heck are you trying to send?");
}
}

private void closeConnection() {
System.out.println("Close connections ...");
try {
    inputStream.close();
    outputStream.close();
    clientSocket.close();
} catch (IOException e) {
    e.printStackTrace();
}
}

private void showMessages(String message) {
SwingUtilities.invokeLater(new Runnable() {

    @Override
    public void run() {
    messageBox.append(message + "\n");
    }
});
}}

The problem is when I start 2 clients and a server and send message, the server throws exception

java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at awesomechat.server.ClientHandler.readMessage(ClientHandler.java:54)
at awesomechat.server.ClientHandler.run(ClientHandler.java:45)

and one client throws

java.io.StreamCorruptedException: invalid type code: AC
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at awesomechat.client.Client.readMessage(Client.java:106)
at awesomechat.client.Client.startClient(Client.java:76)
at awesomechat.client.StartClient.main(StartClient.java:6)

So anyone please show me the point why I get these two exceptions and how to solve it.

  • possible duplicate of [StreamCorruptedException: invalid type code: AC](http://stackoverflow.com/questions/2393179/streamcorruptedexception-invalid-type-code-ac) – Jeremy Stein Oct 13 '14 at 17:34
  • Ya, I read that and understand but I still don't know how to fix that. That's the point :) – Le Silencieux Oct 14 '14 at 01:15
  • The point of the other question already containing the answer is that you only create 1 ObjectOutputStream and ObjectInputStream per Socket Outputstream and Inputstream and re-use them. The method `ServerV2.sendMessage` creates a new ObjectOutputStream every time which is causing the error. – vanOekel Oct 17 '14 at 21:07

0 Answers0