繁体   English   中英

Java SocketChannel读取整个字符串

[英]Java SocketChannel Read Entire String

在我当前的项目中,我试图将字符串从一台计算机传输到另一台计算机,并且在从大量示例中找到并学习之后,我设法获得了一种基本的通信形式。

我遇到的问题是,如果一台计算机尝试发送太长的消息,它似乎被分解成多个部分(大约3700个字符),并且我的解析方法失败。

我正在使用选择器来遍历所有通道。 以下是相关代码:

if(key.isReadable()) {
    // Get the channel and read in the data
    SocketChannel keyChannel = (SocketChannel)key.channel();
    ByteBuffer buffer = buffers.get(keyChannel);
    int length  = 0;
    try {
        length = keyChannel.read(buffer);
    } catch ( IOException ioe) {
        closeChannel(keyChannel);
    }
    if(length > 0) {
        buffer.flip();
        // Gather the entire message before processing
        while( buffer.remaining() > 0) {
            byte[] data = new byte[buffer.remaining()];
            buffer.get(data);
            fireReceiveEvent(keyChannel, data);//Send the data for processing
        }
        buffer.compact();
    } else if (length < 0) {
        closeChannel(keyChannel);
    }
}

如何保证在传递消息之前立即读取整个消息(无论长度如何)?

与许多比我了解更多的人交谈之后。 问题的根源在于,使用TCP不可能知道整个“消息”何时到达,因为没有消息之类的消息,因为TCP在双向字节流上工作。 解决方案是创建您自己的协议并实现您自己的“消息”定义。

对于我的项目,每条消息都以[{开头,并以]}结尾,具体取决于起始字符。 我搜索接收到的数据,如果有完整的消息,则抓取并将其传递给处理程序。 否则,请跳过频道,然后等待更多内容到达。

这是处理消息接收的代码的最终版本。

if(key.isReadable()) {
    // Get the channel and read in the data
    SocketChannel keyChannel = (SocketChannel)key.channel();
    ByteBuffer buffer = buffers.get(keyChannel);
    int length = 0;
    try {
        length = keyChannel.read(buffer);
    } catch ( IOException ioe) {
        key.cancel();
        closeChannel(keyChannel);
    }
    if (length > 0) {
        buffer.flip();
        // Gather the entire message before processing
        if (buffer.remaining() > 0) {
            byte[] data = new byte[buffer.remaining()];
            buffer.get(data);
            buffer.rewind();
            int index = 0;
            int i = 0;
            // Check for the beginning of a packet
            //[ = 91
            //] = 93
            //{ = 123
            //} = 125
            if (data[0] == 91 || data[0] == 123) {
                // The string we are looking for
                byte targetByte = (byte) (data[0] + 2);
                for (byte b : data) {
                    i += 1;
                    if (b == targetByte) {
                        index = i;
                        break;
                    }
                }
                if (index > 0) {
                    data = new byte[index];
                    buffer.get(data, 0, index);
                    fireReceiveEvent(keyChannel, data);
                }
            } else {
                for (byte b : data) {
                    i += 1;
                    if (b == 91 || b == 123) {
                        index = i;
                        break;
                    }
                }
                if (index > 0) {
                    data = new byte[index];
                    buffer.get(data, 0, index); // Drain the data that we don't want
                }
            }
        }
        buffer.compact();
    } else if (length < 0) {
        key.cancel();
        closeChannel(keyChannel);
    }
}

暂无
暂无

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

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