一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Netty 基石,Java NIO 核心知識

Netty 基石,Java NIO 核心知識

2021-12-27 23:32yes的練級攻略是Yes呀 Java教程

在深入 Netty 之前,我覺得有必要先對齊一下 Java NIO 的基礎知識,因為 Netty 對底層網絡 I/O 的操作就是基于 Java NIO 的,所以有必要了解一下。

Netty 基石,Java NIO 核心知識

本文轉載自微信公眾號「yes的練級攻略」,作者是Yes呀 。轉載本文請聯系yes的練級攻略公眾號。

你好,我是yes。

在深入 Netty 之前,我覺得有必要先對齊一下 Java NIO 的基礎知識,因為 Netty 對底層網絡 I/O 的操作就是基于 Java NIO 的,所以有必要了解一下。

到時候看源碼,會有很多概念,例如 Channel、Selector、SelectionKey、Buffer 等等,這篇我們就來了解下這些名詞到底代表著什么,分別是什么意思。

關于 Java NIO 相關的核心,總的來看包含以下三點,分別是:

  • Channel
  • Buffer
  • Selector

什么是 Channel

翻譯過來就是通道。

我們可以往通道里寫數據,也可以從通道里讀數據,它是雙向的,而與之配套的是 Buffer,也就是你想要往一個通道里寫數據,必須要將數據寫到一個 Buffer 中,然后寫到通道里。

從通道里讀數據,必須將通道的數據先讀取到一個 Buffer 中,然后再操作。

在 NIO 中 Channel 有多種類型:

  • SocketChannel
  • ServerSocketChannel
  • DatagramChannel
  • FileChannel
  • SocketChannel

對標 Socket,我們可以直接將它當做所建立的連接。

通過 SocketChannel ,我們可以利用 TCP 協議進行讀寫網絡數據。

ServerSocketChannel

可以對標 ServerSocket,也就是服務端創建的 Socket。

它的作用就是監聽新建連的 TCP 連接,為新進一個連接創建對應的 SocketChannel。

之后,通過新建的 SocketChannel 就可以進行網絡數據的讀寫,與對端交互。

可以看到它主要是用來接待新連接,這功能主要就是服務端做的,所以叫 ServerSocketChannel。

DatagramChannel

看到 Datagram 應該就知道是 UDP 協議了,是無連接協議。

利用 DatagramChannel 可以直接通過 UDP 進行網絡數據的讀寫。

FileChannel

文件通道,用來進行文件的數據讀寫。

我們日常開發主要是基于 TCP 協議,所以我們把精力放在 SocketChannel 和 ServerSocketChannel 上即可。

我們再回過頭來繼續看看 SocketChannel 和 ServerSocketChannel。

SocketChannel 主要在兩個地方出現:

  • 客戶端,客戶端創建一個 SocketChannel 用于連接至遠程的服務端。
  • 服務端,服務端利用 ServerSocketChannel 接收新連接之后,為其創建一個 SocketChannel 。

隨后,客戶端和服務端就可以通過這兩個 SocketChannel 相互發送和接收數據。

ServerSocketChannel 主要出現在一個地方:服務端。

服務端需要綁定一個端口,然后監聽新連接的到來,這個活兒就由 ServerSocketChannel 來干。

服務端內常常會利用一個線程,一個死循環,不斷地接收新連接的到來。

  1. ServerSocketChannel serverSocketChannel
  2. = ServerSocketChannel.open();
  3. ......
  4. while(true){
  5. // 接收的新連接
  6. SocketChannel socketChannel =
  7. serverSocketChannel.accept();
  8. .......
  9. }

至此,想必你應該清楚 ServerSocketChannel 和 SocketChannel 的區別和作用了。

Buffer

Buffer 說白了就是內存中可以讀寫的一塊地方,叫緩沖區,用于緩存數據。

其實還真沒啥好說的,最多就講講 Java NIO Buffer 的 API。

但講 API 的太死板了,所以自己上網搜搜吧。我就告知一個結論,這個 API 很不好用,稍微漏寫了點,就容易出 bug,而且還有很多優化的之處,所以 Netty 沒用 Java NIO Buffer 而是自己實現了一個 Buffer,叫 ByteBuf。

等我們之后分析 ByteBuf 的時候再來盤一盤?,F在你只需要知道 Buffer 主要用來緩存通道的讀寫數據即可。

對了,看到這可能會有人提出疑問,為什么 Channel 必須和 Buffer 搭配使用?

其實網絡數據是面向字節的,但是我們讀寫的數據往往是多字節的,假設不用 Buffer ,那我們就得一個字節一個字節的調用讀和調用寫,想想是不是很麻煩?

所以我們搞個 Buffer,把數據攏一攏,這樣之后的調用才能更好地處理完整的數據,方便異步的處理等等。

Selector

I/O多路復用的核心玩意。

一個 Selector 上可以注冊多個 Channel ,我們從上面得知一個 Channel 就對應了一個連接,因此一個 Selector 可以管理多個 Channel 。

具體管理什么?

當任意 Channel 發生讀寫事件的時候,通過 Selector.select() 就可以捕捉到事件的發生,因此我們利用一個線程,死循環的調用 Selector.select(),這樣可以利用一個線程管理多個連接,減少了線程數,減少了線程的上下文切換和節省了線程資源。

這就是 Selector 的核心功能,然后我們再來細說具體是怎樣管理的。

首先,創建一個 Selector。

  1. Selector selector = Selector.open();

然后,你需要將被管理的 Channel 注冊到 Selector 上,并聲明感興趣的事件。

  1. SelectionKey key = channel.register(selector, Selectionkey.OP_READ);

Netty 基石,Java NIO 核心知識

事件一共有以上四種類型,注冊的時候可以同時對多種類型的事件感興趣,例如:

  1. SelectionKey key
  2. = channel.register(selector,
  3. Selectionkey.OP_READ | SelectionKey.OP_WRITE);

這樣,當這個 Channel 發生讀或寫事件,我們調用 Selector.select() 就可以得知有事件發生。

具體 Selector.select() 有三個重載方法:

  • int selectNow(),不論是否有無事件發生,立即返回
  • int select(long timeout),至多阻塞 timeout 時間(或被喚醒),如果提早有事件發生,提早返回
  • int select(),一直阻塞著,直到有事件發生(或被喚醒)

返回值就是就緒的通道數,一般判斷大于 0 即可進行后續的操作。

后續的操作就是調用:

  1. Set selectedKeys = selector.selectedKeys();

獲得了一個類型為 Set 的 selectedKeys 集合,那這個 selectedKeys 又是啥玩意?

我們來看一下它的方法和成員:

Netty 基石,Java NIO 核心知識

看到這些成員,其實我們就很清晰了,我們可以通過 selectedKey 得知當前發生的是什么事件,有 isAcceptable、isReadable 等等。

然后還能獲得對應的 channel 進行相應的讀寫操作,還有獲取 attachment 等等。

所以得到了 selectedKeys 就可以通過迭代器遍歷所有發生事件的連接,然后進行操作。

大致使用的代碼如下所示:

  1. while(true) {
  2. int readyNum = selector.select();
  3. if (readyNum == 0) {
  4. continue;
  5. }
  6. Set selectedKeys = selector.selectedKeys();
  7. Iterator keyIterator = selectedKeys.iterator();
  8. while(keyIterator.hasNext()) {
  9. SelectionKey key = keyIterator.next();
  10. if(key.isAcceptable()) {
  11. // a connection was accepted by a ServerSocketChannel.
  12. } else if (key.isConnectable()) {
  13. // a connection was established with a remote server.
  14. } else if (key.isReadable()) {
  15. // a channel is ready for reading
  16. } else if (key.isWritable()) {
  17. // a channel is ready for writing
  18. }
  19. keyIterator.remove(); //執行完畢之后,需要在循環內移除自己
  20. }
  21. }

還有個方法就是 Selector.wakeup(),可以喚醒阻塞著的 Selector。

對了還有一點沒說,就是如果 Channel 要和 Selector 搭配,那它必須得是非阻塞的,即配置

  1. channel.configureBlocking(false);

從上面的操作,我們可以得知 Selector 處理事件的時候必須快,如果長時間處理某個事件,那么注冊到 Selector 上的其他連接的事件就不會被及時處理,造成客戶端阻塞。

至此,想必你應該清晰 Selector 具體是如何管理這么多連接的了。

參考:https://ifeve.com/java-nio-all/

原文鏈接:https://mp.weixin.qq.com/s/0p3hId2GCy48yyGH55A5Qg

延伸 · 閱讀

精彩推薦
  • Java教程Java8中Stream使用的一個注意事項

    Java8中Stream使用的一個注意事項

    最近在工作中發現了對于集合操作轉換的神器,java8新特性 stream,但在使用中遇到了一個非常重要的注意點,所以這篇文章主要給大家介紹了關于Java8中S...

    阿杜7482021-02-04
  • Java教程Java實現搶紅包功能

    Java實現搶紅包功能

    這篇文章主要為大家詳細介紹了Java實現搶紅包功能,采用多線程模擬多人同時搶紅包,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙...

    littleschemer13532021-05-16
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經有好久沒有升過級了。升級完畢重啟之后,突然發現好多錯誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程Java BufferWriter寫文件寫不進去或缺失數據的解決

    Java BufferWriter寫文件寫不進去或缺失數據的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進去或缺失數據的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望...

    spcoder14552021-10-18
  • Java教程xml與Java對象的轉換詳解

    xml與Java對象的轉換詳解

    這篇文章主要介紹了xml與Java對象的轉換詳解的相關資料,需要的朋友可以參考下...

    Java教程網2942020-09-17
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關于小米推送Java代碼,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧...

    富貴穩中求8032021-07-12
  • Java教程20個非常實用的Java程序代碼片段

    20個非常實用的Java程序代碼片段

    這篇文章主要為大家分享了20個非常實用的Java程序片段,對java開發項目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
主站蜘蛛池模板: 精品无码久久久久久久动漫 | 521色香蕉网站在线观看 | 好男人在线观看免费高清2019韩剧 | 亚洲成人免费 | 美女主播免费观看 | 美女露全身永久免费网站 | 亚洲 另类 欧美 变态屎尿 | 美女福利视频一区二区 | 免费永久观看美女视频网站网址 | dasd-698黑人在线播放 | 亚洲精品视频网 | 操女人的b | 经典三级四虎在线观看 | 奇米影视4444 | 1313午夜精品久久午夜片 | 亚洲国产99在线精品一区二区 | 韩国甜性涩爱免费观看 | 1024在线视频精品免费 | 日本精品人妖shemale人妖 | 欧美另类变态 | 性伴交换多p | 日韩在线 在线播放 | 挺进白嫩老师下面视频 | 99国产精品久久久久久久... | 国产精品探花一区在线观看 | 成人二区 | 精品视频入口 | 黑人巨大精品战中国美女 | 午夜影院免费体验 | 日本色频| 国产日韩欧美色视频色在线观看 | 91精品导航在线观看 | 小早川怜子息梦精在线播放 | xxx黑人又大粗又长 xxxx性欧美极品另类 | 99久久精品久久久久久清纯 | 91看片淫黄大片欧美看国产片 | 91碰| 亚洲第一页综合 | 色妞视频一级毛片 | 欧美一卡2卡3卡无卡 | 日韩一级片在线免费观看 |