UPDATE: Full code example: Server:
ServerSocket serverSocket = new ServerSocket(8888);
Socket client = serverSocket.accept();
writer_ = new ObjectOutputStream(client.getOutputStream());
writer_.writeObject("This should be a solstice message normally.");
writer_.flush();
Client:
Socket clientSocket = new Socket(InetAddress.getLocalHost(), 8888);
ObjectInputStream reader = new ObjectInputStream(clientSocket.getInputStream());
Object obj = reader.readObject();
if (obj instanceof SolsticeMessage)
{
SolsticeMessage message = (SolsticeMessage) obj;
processMessage(message);
}
else
System.out.println("Received a message of unknown type: " + obj.getClass());
When I run the code, client connects to the server, however It never prints the System.out.println() in the 'else' branch. Additionally, if I change the server as below:
ServerSocket serverSocket = new ServerSocket(8888);
Socket client = serverSocket.accept();
writer_ = new ObjectOutputStream(client.getOutputStream());
writer_.writeObject(message); // of type SolsticeMessage
writer_.flush();
to write a proper message, then the server throws broken pipe exception immediately.
The original question: I am trying to write a simple server that waits for a client to get connected as follows:
ServerSocket serverSocket = new ServerSocket(8888);
Socket client = serverSocket.accept();
writer_ = new ObjectOutputStream(client.getOutputStream());
Then, making sure writer_ is not null, I try to write the following two messages to the client:
writer_.writeObject("This is a string.");
writer_.writeObject(message); // where message implements Serializable
writer_.flush();
Here is the client code:
Socket clientSocket = new Socket(InetAddress.getLocalHost(), 8888);
ObjectInputStream reader = new ObjectInputStream(clientSocket.getInputStream());
Object obj = null;
while ((obj = reader.readObject()) != null)
{
SolsticeMessage message = (SolsticeMessage) obj;
processMessage(message);
}
Contrary to my expectations (where both object should be written), the first objects (String) is sent successfully, however the second object (message) throws the following exception:
java.net.SocketException: Broken pipe
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
at java.io.ObjectOutputStream$BlockDataOutputStream.drain(ObjectOutputStream.java:1847)
at java.io.ObjectOutputStream$BlockDataOutputStream.setBlockDataMode(ObjectOutputStream.java:1756)
at java.io.ObjectOutputStream.writeNonProxyDesc(ObjectOutputStream.java:1257)
at java.io.ObjectOutputStream.writeClassDesc(ObjectOutputStream.java:1211)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1395)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
at java.io.ObjectOutputStream.writeFatalException(ObjectOutputStream.java:1547)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:333)
at com.kivancmuslu.www.solstice.server.SolsticeServer.sendMessage(SolsticeServer.java:146)
at com.kivancmuslu.www.solstice.server.listeners.ResourceChangeListener.processResourceChange(ResourceChangeListener.java:94)
at com.kivancmuslu.www.solstice.server.listeners.ResourceChangeListener.processResourceDelta(ResourceChangeListener.java:65)
at com.kivancmuslu.www.solstice.server.listeners.ResourceChangeListener.processResourceDelta(ResourceChangeListener.java:86)
at com.kivancmuslu.www.solstice.server.listeners.ResourceChangeListener.processResourceDelta(ResourceChangeListener.java:86)
at com.kivancmuslu.www.solstice.server.listeners.ResourceChangeListener.processResourceDelta(ResourceChangeListener.java:86)
at com.kivancmuslu.www.solstice.server.listeners.ResourceChangeListener.resourceChanged(ResourceChangeListener.java:31)
at org.eclipse.core.internal.events.NotificationManager$1.run(NotificationManager.java:291)
at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
at org.eclipse.core.internal.events.NotificationManager.notify(NotificationManager.java:285)
at org.eclipse.core.internal.events.NotificationManager.broadcastChanges(NotificationManager.java:149)
at org.eclipse.core.internal.resources.Workspace.broadcastPostChange(Workspace.java:395)
at org.eclipse.core.internal.resources.Workspace.endOperation(Workspace.java:1530)
at org.eclipse.core.internal.events.AutoBuildJob.doBuild(AutoBuildJob.java:156)
at org.eclipse.core.internal.events.AutoBuildJob.run(AutoBuildJob.java:241)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:53)
Any ideas why string object is written and sent over the network without a problem, however my other serialized object causes this exception? I also attach my Serialized class below just in case it helps:
package com.kivancmuslu.www.solstice.logic;
public class ResourceChangedMessage extends SolsticeMessage
{
/**
*
*/
private static final long serialVersionUID = -2877650023886033398L;
public static enum ResourceChangeType
{
ADDED, REMOVED
}
private final String projectName_;
private final String relativeResourcePath_;
private final ResourceChangeType resourceChangeType_;
public ResourceChangedMessage(String projectName, String relativeResourcePath,
ResourceChangeType resourceChangeType)
{
projectName_ = projectName;
relativeResourcePath_ = relativeResourcePath;
resourceChangeType_ = resourceChangeType;
}
public String getProjectName()
{
return projectName_;
}
public String getRelativeResourcePath()
{
return relativeResourcePath_;
}
public ResourceChangeType getResourceChangeType()
{
return resourceChangeType_;
}
}
where SolsticeMessage is defined as:
package com.kivancmuslu.www.solstice.logic;
import java.io.Serializable;
public abstract class SolsticeMessage implements Serializable
{
private static final long serialVersionUID = 4048501241385740686L;
public abstract String toString();
}
Thank you,
I strongly suspect that the other end of the connection is closing it. For example, if it's another Java program which has code of:
Socket client = serverSocket.accept();
reader_ = new ObjectInputStream(client.getInputStream());
reader_.readObject();
reader_.close();
... then there'd be nowhere for your sending code to send the second object. Unfortunately you haven't given us the code that's listening. The above is my best guess though.
EDIT: Now you've posted your server code, we can see the real problem. Here's what it's trying to read:
while ((obj = reader.readObject()) != null)
{
SolsticeMessage message = (SolsticeMessage) obj;
processMessage(message);
}
... but you're sending it a String
first. So it's trying to cast a String
to a SolsticeMessage
, which will throw an exception - and presumably that is either bringing the whole process down, or at least ending up with a closed connection.