【问题标题】:How to read and write serialized object through SocketChannel in non-blocking mode?非阻塞模式下如何通过SocketChannel读写序列化对象?
【发布时间】:2016-05-05 01:01:02
【问题描述】:

我目前正在尝试通过 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();
}

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

【问题讨论】:

    标签: java serialization nio objectinputstream objectoutputstream


    【解决方案1】:

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

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

    因此,当您一开始不可能写任何东西时,很难看到您是如何到达流标头损坏等的地步的。

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

    【讨论】:

    • 不能通过SocketChannel来完成吗?那么它可以是非阻塞的。
    • 我没说做不到。我说太难了。串行协议最适合流式协议。
    猜你喜欢
    • 1970-01-01
    • 2016-11-14
    • 1970-01-01
    • 2011-10-09
    • 2010-12-13
    • 2011-08-08
    • 1970-01-01
    • 1970-01-01
    • 2012-01-01
    相关资源
    最近更新 更多