最近項目裏,引入了TCP,通過protobuf,在App裏來獲取司機的經緯度信息。還使用到了Netty,本篇先對涉及到的基礎知識做了梳理。
Socket套接字之間的連接過程分爲三個步驟:
- 服務器監聽
- 客戶端請求
- 連接確認。
Java NIO的通道類似流,但又有些不同:
- 流只是在一個方向上移動(一個流必須是 InputStream 或者 OutputStream 的子類),而通道可以用於讀、寫或者同時用於讀寫,是全雙工的。
- 通道可以異步地讀寫。
- 通道中的數據總是要先讀到一個Buffer,或者總是要從一個Buffer中寫入。
Buffer的理解
- position ,limit,capacity機制,讀和寫兩種
- Buffer與Channel之間的讀和寫操作,分爲一對一,一對多,多合一,三種方式。
- buffer.flip()切換到讀模式。clear()方法會清空整個緩衝區。compact()方法只會清除已經讀過的數據。
- buffer.marker(),buffer.reset()連用。通過調用Buffer.mark()方法,可以標記Buffer中的一個特定position。之後可以通過調用Buffer.reset()方法恢復到這個position。
寫入Buffer(讀取buffer類似)
- channel.read(buffer)
- buffer.put(byte b)
Channel的理解
這些是Java NIO中最重要的通道的實現:
- FileChannel。FileChannel實例的size()方法將返回該實例所關聯文件的大小。FileChannel.force()方法將通道里尚未寫入磁盤的數據強制寫到磁盤上。出於性能方面的考慮,操作系統會將數據緩存在內存中,所以無法保證寫入到FileChannel裏的數據一定會即時寫到磁盤上。要保證這一點,需要調用force()方法。
- DatagramChannel,面向UDP
- SocketChannel
- ServerSocketChannel
默認實現是阻塞式的,需要異步非阻塞式的,調用方法socketChannel.configureBlocking(false)
Selector的理解
Selctor的建立
Selector selector = Selector.open();
SelectionKey對象
interest集合是你所選擇的感興趣的事件集合。int interestSet = selectionKey.interestOps();
有以下幾個:- SelectionKey.OP_CONNECT
- SelectionKey.OP_ACCEPT
- SelectionKey.OP_READ
- SelectionKey.OP_WRITE
ready集合是通道已經準備就緒的操作的集合。int readySet = selectionKey.readyOps();。
- selectionKey.isAcceptable();
- selectionKey.isConnectable();
- selectionKey.isReadable();
- selectionKey.isWritable();
從SelectionKey訪問Channel和Selector很簡單。如下:
- Channel channel = selectionKey.channel();
- Selector selector = selectionKey.selector();
Pipe的理解
Pipe有一個source通道和一個sink通道。
創建
1 Pipe pipe = Pipe.open();
sink通道創建
Pipe.SinkChannel sinkChannel = pipe.sink();
source通道
Pipe.SourceChannel sourceChannel = pipe.source();
Java NIO和IO的主要區別
下表總結了Java NIO和IO之間的主要差別
- IO 面向流,阻塞IO
- NIO,面向緩衝, 非阻塞IO,選擇器
Java IO 管道
一個線程通過PipedOutputStream寫入的數據可以被另一個線程通過相關聯的PipedInputStream讀取出來。