亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Java NIO 套接字通道僅在關閉輸出后發送數據。這是為什么呢?

Java NIO 套接字通道僅在關閉輸出后發送數據。這是為什么呢?

Helenr 2022-09-22 15:45:57
我正在嘗試編寫一個程序,該程序接受java nio套接字通道連接,但也使它們保持打開狀態。因此,假設客戶端發送了一條消息,那么服務器是否應該立即發送相同的消息(簡單回顯服務器),但應答過程不起作用。如果客戶端發送新消息,服務器將不會響應,直到我關閉客戶端的套接字通道。但是,在我關閉客戶端的頻道后,所有先前發送的消息將一次性進入。(抱歉我的英語不好,這不是我的母語)寫入過程用于服務器端和客戶端。寫作過程:try {    final ByteBuffer byteBuffer = ByteBuffer.wrap(data);    while(byteBuffer.hasRemaining()){        socketChannel.write(byteBuffer);    }    byteBuffer.flip();} catch (IOException exception) {    throw new BloumException(exception.getMessage());}閱讀過程:final ByteBuffer byteBuffer = ByteBuffer.allocate(DefaultConnectionCreator.this.getDefaultBufferSize());                    try {        while(socketChannel.read(byteBuffer) != -1){                //byteBuffer.clear();        }    } catch (IOException exception) {        exception.printStackTrace();        throw new BloumException(exception.getMessage());    }    return byteBuffer.array();關鍵選擇過程(自動關閉返回假):private void handleKeys(final ServerSocketChannel serverSocketChannel, Set<SelectionKey> keys, HashMap<SocketChannel, ByteBuilder> sessions) throws Exception{        final Iterator<SelectionKey> iterator = keys.iterator();        while(iterator.hasNext()){            final SelectionKey selectionKey = iterator.next();            iterator.remove();            if(selectionKey.isValid()){                if(selectionKey.isAcceptable()){                    final ServerSocketChannel serverSocketChannel2 = (ServerSocketChannel)selectionKey.channel();                    final SocketChannel socketChannel = serverSocketChannel2.accept();                    socketChannel.configureBlocking(false);                    socketChannel.register(selectionKey.selector(), SelectionKey.OP_READ);                    sessions.put(socketChannel, new ByteBuilder());                                        }        }    }
查看完整描述

1 回答

?
繁花如伊

TA貢獻2012條經驗 獲得超12個贊

你好,你有很多錯誤

  1. 您需要在寫入之前翻轉緩沖區

  2. 如果讀取為 -1,則必須關閉通道

  3. 不要創建一個1GB字節的緩沖區,使用的大小是256,1024,4096,8196我建議4096。

  4. 使用直接緩沖區,直接內存已被證明自己在I / O方面更快,因為它不會被垃圾回收器中斷

  5. 沒有布爾值的 if 語句將布爾值設置為等于該語句

  6. 沒有一個忽略讀取字節的while循環,如果它是0,則表示您沒有任何要讀取的內容,導致您循環直到套接字關閉

  7. 我很確定你在那里刪除0的循環是刪除沒有添加的數據,但你可以這樣做,或者如果你翻轉緩沖區,那么Arrays.copyOfRange(buffer.array(), 0, buffer.position())Arrays.copyOfRange(buffer.array(), 0, buffer limit())


查看完整回答
反對 回復 2022-09-22
  • 1 回答
  • 0 關注
  • 143 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號