簡體   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