Java NIO SocketChannelServer无法将第二个对象发送到Socket Client

时间:2018-03-29 12:22:45

标签: java nio java-io

我已经实现了一个基于NIO的SocketChannerl服务器,它将JOB委托给Socket客户端。

服务器能够将第一个作业java对象成功发送给客户端。发送第二个对象时,我在客户端看到以下异常:

java.io.StreamCorruptedException: invalid type code: AC
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1381)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:373)
    at org.cloudcoder.builder2.server.Builder2Server.safeReadObject(Builder2Server.java:370)
    at org.cloudcoder.builder2.server.Builder2Server.runOnce(Builder2Server.java:294)
    at org.cloudcoder.builder2.server.Builder2Server.run(Builder2Server.java:273)
    at java.lang.Thread.run(Thread.java:745) 

由于此原因,客户端断开连接并重新连接到服务器。即使重新连接后,第一个对象也会成功传输到客户端;第二个对象发送失败,这进入循环。

从其他各种SO问题中,我知道如果我们在服务器端使用新的OOS每次向客户端发送数据,就会发生这种异常。为了编写Java对象,我正在使用SocketChannerl.write API。

对象发送代码:

// Generate the ByteBuffer from Submission object
Job job = getNextJobToProcess();
ByteBuffer jobByteBuffer = getBuffer(job);

if (jobByteBuffer != null) {
   LOGGER.info("Capacity of buffer is {}", jobByteBuffer.capacity());
   while(jobByteBuffer.hasRemaining()) {
       int noOfSourceCodeBuffer = socketChannel.write(sourceCodeBuffer);
       LOGGER.info("{} no of bytes of job buffer written to the socket " 
          +  "channel {}", noOfSourceCodeBuffer, this);
   }
   success = true;
}

Job Java Object to ByteBuffer转换器:

/**
 * Utility method generates byte buffer from a object which ISA {@link Serializable}
 *
 * @param obj instance of {@link Serializable}
 * @return ByteBuffer
 * @throws IOException
 */
private ByteBuffer getBuffer(final Serializable obj) throws IOException {
    // Create ByteArrayOutputStream and ObjectOutputStream
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);

    // write the Serializable object into ObjectOutputStream
    objectOutputStream.writeObject(obj);

    // Create a ByteBuffer with the size of byteArrayOutputStream
    ByteBuffer buffer = ByteBuffer.allocate(byteArrayOutputStream.size());

    // copy the ByteArrayOutputStream content to ByteBuffer
    buffer.put(byteArrayOutputStream.toByteArray());

    // mark it for read
    buffer.flip();

    return buffer;
}

根据设计,NIO服务器接受来自旧版java.net.Socket客户端的连接。连接客户端后,NIO服务器开始将JOB委托给客户端;然后客户端处理JOB并将结果发送回服务器。一旦服务器收到结果,它就认为客户端是空闲的,并准备好发送下一个JOB。此链将继续,直到客户端明确关闭。

0 个答案:

没有答案