Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/349.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在非阻塞模式下通过SocketChannel读写序列化对象?_Java_Serialization_Nio_Objectinputstream_Objectoutputstream - Fatal编程技术网

Java 如何在非阻塞模式下通过SocketChannel读写序列化对象?

Java 如何在非阻塞模式下通过SocketChannel读写序列化对象?,java,serialization,nio,objectinputstream,objectoutputstream,Java,Serialization,Nio,Objectinputstream,Objectoutputstream,我目前正试图通过NIO SocketChannel读写序列化对象。此SocketChannel处于非阻塞模式。我似乎找不到正确的方法来做这件事,而不破坏流,破坏流头,等等 这是我目前的写作方法 private void writeData(SelectionKey key) throws IOException { Packet outPacket = null; synchronized (pendingPacketQue) { for (Packet pack

我目前正试图通过NIO SocketChannel读写序列化对象。此SocketChannel处于非阻塞模式。我似乎找不到正确的方法来做这件事,而不破坏流,破坏流头,等等

这是我目前的写作方法

private void writeData(SelectionKey key) throws IOException {
    Packet outPacket = null;
    synchronized (pendingPacketQue) {
        for (Packet packet : pendingPacketQue) {
            if (packet.getChannel().keyFor(selector).equals(key)) {
                outPacket = packet;
                break;
            }
        }
    }
    if (outPacket == null) {
        Logger.writeException("Couldn't find out bound packet in list.", LogType.SERVER);
        return;
    }
    SocketChannel connection = (SocketChannel) outPacket.getChannel();
    ObjectOutputStream outStream = new ObjectOutputStream(connection.socket().getOutputStream());
    outStream.writeObject(outPacket);
    outStream.flush();
    outStream.close();
    connection.keyFor(selector).interestOps(SelectionKey.OP_READ);
}
这是我目前的阅读方法

private void readData(SelectionKey key) throws IOException, ClassNotFoundException {
    SocketChannel connection = (SocketChannel) key.channel();
    buffer.clear();
    int byteCount;
    try {
        byteCount = connection.read(buffer);
    } catch (IOException e) {
        Logger.writeException("Connenction terminated.", LogType.SERVER);
        connection.close();
        key.cancel();
        return;
    }
    if (byteCount == -1) {
        Logger.writeException("Connection error. Terminating connection.", LogType.SERVER);
        key.channel().close();
        key.cancel();
        return;
    }
    Engine.getInstance().getPacketProcessor().processData(connection, buffer.array(), byteCount);
}

public void processData(SocketChannel connection, byte[] data, int count)
        throws IOException, ClassNotFoundException {
    ByteArrayInputStream byteStream = new ByteArrayInputStream(data);
    ObjectInputStream inStream = new ObjectInputStream(byteStream);
    addToQue(inStream.readObject());
    inStream.close();
}

如果您有任何问题,请随时提问。谢谢大家!

您不必在一次读取中读取整个对象

你也不能这样写。您不能在非阻塞模式下使用
SocketChannel
的套接字流。您应该在发件人中获得一个
非法阻止模式异常

因此,很难看出,当您一开始不可能编写任何内容时,您怎么可能会出现损坏的流头等问题


无论如何,我强烈建议你不要这样做。太难了。您需要将对象的大小发送到对象之前,以便知道何时已全部读取、发出多次读取并保存结果,直到全部读取、运行等。直接使用
java.net.Socket
和普通对象输入和输出流。

您不必在一次读取中读取整个对象

你也不能这样写。您不能在非阻塞模式下使用
SocketChannel
的套接字流。您应该在发件人中获得一个
非法阻止模式异常

因此,很难看出,当您一开始不可能编写任何内容时,您怎么可能会出现损坏的流头等问题


无论如何,我强烈建议你不要这样做。太难了。您需要将对象的大小发送到对象之前,以便知道何时已全部读取,发出多次读取并保存结果,直到全部读取完毕,然后运行等。直接使用
java.net.Socket
和正常的对象输入和输出流。

不能通过SocketChannel完成吗?所以它可以是非阻塞的。我没说它不能做到。我说这太难了。串行协议与流式协议配合使用效果最好。难道不能通过SocketChannel完成吗?所以它可以是非阻塞的。我没说它不能做到。我说这太难了。串行协议与流协议配合使用效果最佳。