This is my first post at Stack Overflow, so I hope I'm doing it with a minimum of decency.
I tried to implement a simple solution using Java sockets, but I'm having an exception. I'm surely misusing the APIs, but I can't figure out why and where.
The Client needs to send several binary messages to a Server and it (the Client) must reuse the same socket.
In the Server, I've created one thread that does two things: (1) accepts client requests and (2) instantiates a new thread (running a ClientWorker instance) to handle the client requests.
If I just send one message from the Client, everything work fine. Nevertheless, when I try to send multiple messages, during the second message I have a the following exception:
java.io.StreamCorruptedException: invalid type code: AC at java.io.ObjectInputStream.readObject0(Unknown Source) at java.io.ObjectInputStream.readObject(Unknown Source) at simple.socketexample.ClientWorker.run(ClientWorker.java:26) at java.lang.Thread.run(Unknown Source)
The exception happens in my ClienWorker class, in the line "Message message = (Message)in.readObject();" Note that the first message is always successfully received by the server.
The following classes are part of a simple example that I've created just to show this error.
The first class is the Message:
package simple.socketexample;
import java.io.Serializable;
public class Message implements Serializable {
private static final long serialVersionUID = 4473470814745876900L;
private String text;
private int number;
public Message(String text, int number) {
super();
this.text = text;
this.number = number;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
@Override
public String toString() {
return "Message [text=" + text + ", number=" + number + "]";
}
}
This is my Client:
public class Client {
private final int SERVER_PORT = 3456;
private final String SERVER_HOST = "localhost";
private Socket serverSocket;
public void connect() throws IOException, UnknownHostException {
serverSocket = new Socket(SERVER_HOST, SERVER_PORT);
}
public void disconnect() throws IOException {
serverSocket.close();
}
public void sendMessage(Message message) throws IOException {
ObjectOutputStream out = new ObjectOutputStream(serverSocket.getOutputStream());
out.writeObject(message);
out.flush();
out.reset();
}
}
The Server:
public class Server {
private final int SERVER_PORT = 3456;
public void start() throws IOException {
Thread acceptConnectionsThread = new Thread(new Runnable() {
public void run() {
// Instantiates the socket
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(SERVER_PORT);
} catch (IOException e) {
e.printStackTrace();
}
// Starts accepting client connections
while(true) {
Socket socketFromClient = null;
try {
socketFromClient = serverSocket.accept();
} catch (IOException e) {
e.printStackTrace();
}
// Create a new "client dedicated thread"
ClientWorker clientWorker = new ClientWorker(socketFromClient);
Thread clientDedicatedThread = new Thread(clientWorker);
clientDedicatedThread.start();
}
}
});
acceptConnectionsThread.start();
}
}
My ClientWorker:
public class ClientWorker implements Runnable {
private Socket socketFromClient;
public ClientWorker(Socket socketFromClient) {
super();
this.socketFromClient = socketFromClient;
}
public void run() {
ObjectInputStream in = null;
try {
in = new ObjectInputStream(socketFromClient.getInputStream());
} catch (IOException e) {
e.printStackTrace();
return;
}
while(true) {
try {
Message message = (Message)in.readObject();
System.out.println(message);
} catch (ClassNotFoundException e) {
e.printStackTrace();
break;
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}
}
And the class that I've used to test this: package simple.socketexample;
import java.io.IOException;
/**
* Hello world!
*
*/
public class App {
public static void main(String[] args) throws Exception {
// Start the server in a new (background) thread
Thread serverInBackground = new Thread(new Runnable() {
public void run() {
Server server = new Server();
try {
server.start();
} catch (IOException e) {
e.printStackTrace();
}
}
});
serverInBackground.start();
// Client and connect a client
Client client = new Client();
client.connect();
// Sending one message to the server
client.sendMessage(new Message("MessageOne", 1));
// Sending another message to the server
client.sendMessage(new Message("MessageTwo", 2));
// Closing the client
client.disconnect();
}
}
The problem will probably be in a small detail and the solution may be also be right in front of my nose, but somehow I can't see it. Have anyone faced a similar problem? How did you solve it?
Many thanks and kind regards.
Try this ClientWorker
public class ClientWorker implements Runnable {
private Socket socketFromClient;
public ClientWorker(Socket socketFromClient) {
super();
this.socketFromClient = socketFromClient;
}
public void run() {
while(true) {
ObjectInputStream in = null;
try {
in = new ObjectInputStream(socketFromClient.getInputStream());
} catch (IOException e) {
e.printStackTrace();
return;
}
try {
Message message = (Message)in.readObject();
System.out.println(message);
} catch (ClassNotFoundException e) {
e.printStackTrace();
break;
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}
}
and comment the reset() in Client
public void sendMessage(Message message) throws IOException {
ObjectOutputStream out = new ObjectOutputStream(serverSocket.getOutputStream());
out.writeObject(message);
out.flush();
// out.reset();
}