Java 接收到多个数据包的StreamCorruptedException
我有一个客户机-服务器应用程序,其中使用java serversocket(服务器端)和带有java.nio选择器功能的Socket(客户端)。我通过ObjectInput/Output流使用序列化对象在客户端和服务器之间交换消息 下面是从服务器接收消息的scala代码,这是相当标准的Java 接收到多个数据包的StreamCorruptedException,java,serialization,nio,Java,Serialization,Nio,我有一个客户机-服务器应用程序,其中使用java serversocket(服务器端)和带有java.nio选择器功能的Socket(客户端)。我通过ObjectInput/Output流使用序列化对象在客户端和服务器之间交换消息 下面是从服务器接收消息的scala代码,这是相当标准的 enter code here var msg:CommunicationMessage = null var buf:ByteBuffer = ByteBuffer.allocate(1024);
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
除了服务器在很短的时间内写入多条消息,客户机在缓冲区中同时接收这些消息并导致StreamCorruptedException的情况外,其他情况都可以正常工作。据我所知,objectinputstream无法在传入字节流中的多个序列化对象之间进行分隔,因此它会抛出此无效流错误。而且,即使我已经为捕捉它设置了例外,程序仍然挂起
有什么解决办法
1) 基于某个长度字段在消息中创建我自己的分隔符,以标识消息边界
2) 我还读到了在每次接收后关闭插座并启动新插座的内容。不知道这会有什么帮助
请允许我建议
提前感谢您需要在内容之前发送打包的
ObjectOutputStream
的长度。然后,您就可以确切地知道有多少传入数据属于每个流,并且可以相应地通过tearrayinputstream构建