I have a client server application where I am using java serversocket(server side) and sockets (client side) with the java.nio selector facility. I am exchanging messages between the client and server using serialized objects via ObjectInput/Output Streams.
Here is the scala code for receiving the message from server which is fairly standard
enter code here
var msg:CommunicationMessage = null
var buf:ByteBuffer = ByteBuffer.allocate(1024);
var numBytesRead:Int = 0
try {
// Clear the buffer and read bytes from socket
buf.clear();
//println("Before Read")
numBytesRead = sChannel.read(buf)
//println("After Read " + numBytesRead)
numBytesRead match {
case -1 =>
println("Something Wrong with the Channel")
case 0 =>
//println("Nothing to read")
case _ =>
//println("Read some bytes")
// To read the bytes, flip the buffer
buf.flip();
// Read the bytes from the buffer ...;
// see Getting Bytes from a ByteBuffer
val bis:ByteArrayInputStream = new ByteArrayInputStream (buf.array());
val ois:ObjectInputStream = new ObjectInputStream (bis);
msg = ois.readObject().asInstanceOf[CommunicationMessage];
println("\n\n")
println("Received Message from Server")
msg.msgType match {
case CommunicationConstants.COMM_MSG_TYPE_RSP =>
println("updating server info")
updateServerInfo(msg.msgData)
case CommunicationConstants.COMM_MSG_TYPE_IND =>
if (serverAccepted) updateClientUI(msg)
}
}
} catch {
case e:StreamCorruptedException =>
println("Stream Corruption Exception received " + e.getCause())
case e:IOException =>
// Connection may have been closed
println("IO Exception received" + e.getCause())
}
enter code here
Everything works fine except for situations when the server writes multiple messages within a very short span of time and the client receives them together in the buffer and causes StreamCorruptedException. As I understand , the objectinputstream cannot delimit between multiple serialized objects in the incoming byte stream hence it throws this invalid stream error. Also even I have put the exception for catching it , the program still hangs.
What could be a solution for this. ?
1) Creating my own delimiters in the message based on some length field to identify the message boundary.
2) I also read somewhere to close the socket after every receive and start a new one. Not sure how will this help.
Plz suggest.
Thanks in advance
You need to send the length of the packetized
ObjectOutputStreamahead of its contents. Then you know exacly how much incoming data belongs to each stream and you can construct yourByteArrayInputStreamaccordingly.