我正在嘗試編寫一個程序,該程序接受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,則必須關閉通道
不要創建一個1GB字節的緩沖區,使用的大小是256,1024,4096,8196我建議4096。
使用直接緩沖區,直接內存已被證明自己在I / O方面更快,因為它不會被垃圾回收器中斷
沒有布爾值的 if 語句將布爾值設置為等于該語句
沒有一個忽略讀取字節的while循環,如果它是0,則表示您沒有任何要讀取的內容,導致您循環直到套接字關閉
我很確定你在那里刪除0的循環是刪除沒有添加的數據,但你可以這樣做,或者如果你翻轉緩沖區,那么
Arrays.copyOfRange(buffer.array(), 0, buffer.position())
Arrays.copyOfRange(buffer.array(), 0, buffer limit())
添加回答
舉報
0/150
提交
取消