最近用SocketChannel進行網絡編程比較多,中間也遇到了幾個問題,出現的bug也主要來自於對於ByteBuffer的使用不當。如今終於調通了,對ByteBuffer及Socket網絡編程也有了更深的認識,特此總結一下。編程
對於ByteBuffer主要須要注意的是幾個標誌的含義:position,limit,capability,mark.幾個操做的影 響:flip(),clear(),rewind().還有就是在讀取或者寫入時,標誌的變化,好比get()方法致使position加1.數組
SocketChannel採用的是非阻塞異步讀取流數據,在讀取的時候,一般是網絡
若是流中有數據,就會把數據從position開始讀到ByteBuffer中,在讀取以前ByteBuffer的clear操做會把 position置爲0,limit置爲capability,也就是至關於清空了以前的內容,可是ByteBuffer中數組的內容在read以前是沒 有改變的.app
read以後,一般就是開始從ByteBuffer中提取讀到的數據,若是你的數據是以本身定義的數據包的格式進行發送的,那你還須要判斷是否讀到 了數據包的結尾,由於對流數據自己來講是沒有結尾這一說的。在提取數據以前,要先把position放到開始讀取時的位置,把limit放到當前位置,所 以要flip一下,表示從position到limit的位置都是須要的數據。異步
這樣以來也存在一個問題,當一次讀到的ByteBuffer不包含完整的數據包或者包含多個數據包.那麼就須要在下一次繼續把這些包分拆出來.那麼在讀取數據的代碼處就能夠改成,這樣就把以前讀取到的未完整的包保留了下來:工具
另一個可能會用到的操做就是ByteBuffer.rewind(),他會把position置爲0,limit保持不變,能夠用於重複讀取一段數據.ui
ByteBuffer是nio中一個很是方便的工具.設計思想也很是值得借鑑.spa