简体   繁体   English

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

[英]How to read and write serialized object through SocketChannel in non-blocking mode?

I am currently attempting to read and write serialized Objects through a NIO SocketChannel. 我目前正在尝试通过NIO SocketChannel读取和写入序列化的对象。 This SocketChannel is in non-blocking mode. 此SocketChannel处于非阻塞模式。 I can't seem to find the right way to do it without corrupting the stream, corruping the stream header, etc... 我似乎找不到不破坏流,破坏流头等的正确方法。

This is my current write method 这是我目前的写方法

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);
}

This is my current read method 这是我目前的阅读方法

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();
}

If you have any questions feel free to ask. 如果你有任何问题随时问。 Thank you! 谢谢!

You haven't necessarily read the entire object in a single read. 您不必一次读取整个对象。

You can't do your writing this way either. 您也无法以这种方式进行写作。 You can't use the streams of a socket of a SocketChannel in non-blocking mode. 您不能在非阻塞模式下使用SocketChannel的套接字流。 You should have got an IllegalBlockingModeException in the sender. 您应该在发送IllegalBlockingModeException收到一个IllegalBlockingModeException

Hard to see therefore how you could possibly have got to the point of corrupted stream headers etc. when you can't possibly have written anything in the first place. 因此,当您一开始可能无法编写任何内容时,很难看到如何到达损坏的流头等。

In any case I strongly recommend you don't attempt this. 无论如何,我强烈建议您不要尝试此操作。 It's too hard. 太难了。 You need to send the size of the object ahead of the object so you know when you've read it all, issue multiple reads and save the results until you have it all, run etc etc etc. Use java.net.Socket and the normal object input and output streams directly. 您需要将对象的大小发送到对象之前,以便知道所有内容的读取时间,发出多次读取并保存结果,直到全部读取,运行等,等等。使用java.net.Socket和普通对象直接输入和输出流。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM