收到多个数据包的StreamCorruptedException

时间:2012-04-11 08:06:46

标签: java serialization nio

我有一个客户端服务器应用程序,我在其中使用java服务器端(服务器端)和带有java.nio选择器工具的套接字(客户端)。我正在使用序列化对象通过ObjectInput / Output Streams在客户端和服务器之间交换消息。

这是用于从服务器接收消息的scala代码,这是相当标准的

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)我也在每次接收后读取某个地方关闭套接字并开始一个新套接字。不确定这会有什么帮助。

Plz建议。

提前致谢

1 个答案:

答案 0 :(得分:0)

您需要在其内容之前发送打包ObjectOutputStream的长度。然后你就知道每个流有多少传入数据,你可以相应地构建你的ByteArrayInputStream