Android開發(fā)之使用Netty進行Socket編程(一)

一些基本概念

1 Socket

1) 同一個名詞Socket有多種不同意思。
2) 在計算機網(wǎng)絡(luò)知識體系中,運輸層的TCP(傳輸控制協(xié)議)把連接作為最基本的抽象。TCP的連接有兩個端點,被稱為Socket,通過IP地址+端口號來區(qū)分來自不同應(yīng)用程序進程或網(wǎng)絡(luò)連接的通信,實現(xiàn)數(shù)據(jù)傳輸?shù)牟l(fā)服務(wù)。Client進程和Server進程之間是通過Socket讀寫數(shù)據(jù)進行通信的。
3) JDK的java.net包下有兩個類:SocketServerSocket,在Client和Server建立連接成功后,兩端都會產(chǎn)生一個Socket實例,操作這個實例,完成所需的會話,而程序員就通過這些API進行網(wǎng)絡(luò)編程。 Socket連接過程分為三個步驟:服務(wù)器監(jiān)聽,客戶端請求,連接確認(rèn)。需要注意的是,Socket自己并不是一種協(xié)議,而是對TCP/IP協(xié)議的抽象,并提供最基本的函數(shù)接口方便開發(fā)者調(diào)用。

2 Netty

Netty.io官網(wǎng)介紹:
Netty是一個異步非阻塞的事件驅(qū)動型的網(wǎng)絡(luò)應(yīng)用程序框架。滿足高性能協(xié)議服務(wù)器和客戶端的快速發(fā)展需求。
Netty是一個高性能、方便開發(fā)的NIO框架,使用它可以簡單快速地開發(fā)網(wǎng)絡(luò)應(yīng)用程序,比如客戶端和服務(wù)端的協(xié)議。Netty大大簡化了網(wǎng)絡(luò)編程比如TCP和UDP的 Socket的開發(fā)。
“快速和簡單”并不意味著應(yīng)用程序會有難維護和性能低的問題,Netty是一個精心設(shè)計的框架,它從FTP、SMTP、HTTP、許多二進制和基于文本的傳統(tǒng)協(xié)議實現(xiàn)中吸收了經(jīng)驗,為我們提供了一個高開發(fā)效率、高性能、穩(wěn)定、可伸縮的解決方案。

3 NIO

剛剛提到:

Netty是一個NIO框架。

理解NIO框架的基本概念有助于學(xué)習(xí)Netty提供給開發(fā)者使用的API。
NIO 是jdk1.4 里提供的新API,全稱即java new I/O。Sun 官方標(biāo)榜的特性如下: 為所有的原始類型提供緩存(Buffer)支持。
首先我們來回憶一下Java的IO

  1. IO可以簡單理解為 數(shù)據(jù)流方向:程序→硬盤寫數(shù)據(jù)(Output)以及 硬盤→程序讀數(shù)據(jù)(Input),同時Java IO是基于流(Stream)的,所有的API都繼承自InputStream/OutputStream。意味著每次從流中讀一個或多個字節(jié),直至讀取所有字節(jié),它們沒有被緩存在任何地方。
  2. IO的過程是阻塞的,也就是說當(dāng)一個線程調(diào)用read() 或 write()時,該線程被阻塞,直到有一些數(shù)據(jù)被讀取,或數(shù)據(jù)完全寫入。該線程在此期間不能再干任何事情了。

然后我們再來看NIO:
NIO包括三個核心:

  • Channels
    FileChannel、DatagramChannel、SocketChannel、ServerSocketChannel這些通道涵蓋了UDP 和 TCP 網(wǎng)絡(luò)IO,以及文件IO。
    Java NIO的通道類似流,但又有些不同:
    1)流只是在一個方向上移動(一個流必須是 InputStream 或者 OutputStream 的子類),而通道可以用于讀、寫或者同時用于讀寫,是全雙工的。
    2)通道可以異步地讀寫。
    3)通道中的數(shù)據(jù)總是要先讀到一個Buffer,或者總是要從一個Buffer中寫入。
    Channel

    實際上Channel可以分為兩大類,分別是用于網(wǎng)絡(luò)讀寫的SelectableChannel和用于文件操作的FileChannel。
    Netty中ServerSocketChannel和SocketChannel都是SelectableChannel的子類 。
  • Buffers
    所有數(shù)據(jù)都是用緩沖區(qū)進行處理的。在讀取數(shù)據(jù)時,它是直接讀到緩沖區(qū)中;在寫入數(shù)據(jù)時,它也是寫入到緩沖區(qū)中。任何時候訪問 NIO 中的數(shù)據(jù),我們都是通過緩沖區(qū)進行讀寫操作。
    緩沖區(qū)本質(zhì)上是一塊可以寫入數(shù)據(jù),然后可以從中讀取數(shù)據(jù)的內(nèi)存。這塊內(nèi)存被包裝成NIO Buffer對象,并提供了一組方法,用來方便的訪問該塊內(nèi)存。
    NIO中Buffer的實現(xiàn)包括ByteBuffer、CharBuffer、DoubleBuffer等等,這些Buffer覆蓋了你能通過IO發(fā)送的基本數(shù)據(jù)類型:byte, short, int, long, float, double 和 char。
Buffer
  • Selectors
    Selector(選擇器)是Java NIO中能夠檢測一到多個NIO通道,并能夠知曉通道是否為諸如讀寫事件做好準(zhǔn)備的組件。
    Selector允許單線程處理多個 Channel。如果你的應(yīng)用打開了多個連接(通道),但每個連接的流量都很低,使用Selector就會很方便。例如,在一個聊天服務(wù)器中。
    Selector

    Selector會不斷的輪詢注冊在其上的Channel,如果某個Channel上面有新的TCP連接接入、讀和寫事件,這個Channel就處于就緒狀態(tài),會被Selector輪詢出來,然后通過SelectionKey可以獲取就緒Channel的集合進行后續(xù)的IO操作。

所以,與IO相比,

  1. NIO是從緩沖區(qū)(Buffer)讀寫數(shù)據(jù)的,而不是面向流(Stream)。例如在讀取硬盤數(shù)據(jù)時,并不是僅從一個InputStream上逐字節(jié)讀取,而是數(shù)據(jù)必須先讀入緩沖區(qū)再處理。
  2. NIO在一個線程從某通道發(fā)送請求讀取數(shù)據(jù),并不會保持線程阻塞,所以直至數(shù)據(jù)變的可以讀取之前,該線程可以繼續(xù)做其他的事情。 非阻塞寫也是如此。一個線程請求寫入一些數(shù)據(jù)到某通道,但不需要等待它完全寫入,這個線程同時可以去做別的事情。 線程通常將非阻塞IO的空閑時間用于在其它通道上執(zhí)行IO操作,所以一個單獨的線程現(xiàn)在可以管理多個輸入和輸出通道(channel)。

最后

抱歉這是一篇搬運后排版出來的文章,花了點時間整理了下Netty框架相關(guān)的知識。尤其是NIO這一塊,雖然網(wǎng)上的言論都是不建議直接基于JDK的NIO類庫進行開發(fā),幾乎都推薦使用Netty開發(fā)NIO服務(wù)端,但是了解NIO的一些核心概念,肯定有助于對Netty整個代碼模式以及API使用的學(xué)習(xí)。這兩天會再整理一下在Android客戶端開發(fā)中Netty的具體使用。

相關(guān)鏈接

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容