Java.nio中的主要類
ServerSocketChannel:ServerSocket的替代類.
SocketChannel:Socket的替代類
Selector:為ServerSocketChannel監控接受就緒事件,為SocketChannel監控連接就緒,讀就緒和寫就緒事件
SelectionKey:代表ServerSocketChannel及SocketChannel向Selector注冊事件句柄
向SocketChannel和ServerSocketChannel注冊事件:
SelectionKey key=serverSocketChannel.register(selector,op)
Op的可選值
對于ServerSocketChannel只有一個事件:
(1)SelectionKye.OP_ACCEPT:接受連接就緒事件,表示至少有了一個客戶連接,服務器可以接受這個連接
SocketChannel可能發生3種事件
(1)SelectionKey.OP_CONNECT:連接就為事件,表示客戶與服務器的連接已經成功
(2)SelectionKey.OP_WRITE/OP_READ:寫的就緒事件,表示已經可以向輸出流寫數據了SocketChannel提供了接受和發送的方法
可以使用:read(ByteBuffer)write(ByteBuffer)寫入寫出
?ServerSocketChannel類
方法:(PS繼承過SelectableChannel類的方法)
??? (1)open()靜態方法獲取ServerSocketChannel對象.
???? (2)accept同ServerSocket,不過獲取的是SocketChannel,根據是否阻塞返回null還是阻塞,值得注意的是accept返回的SocketChannel是阻塞模式的使用configureBlocking更改模式
???? (3)socket() 返回關聯的ServerSocket
SocketChannel類
此類是Socket類的替代類?
方法:(PS繼承過SelectableChannel類的方法)
(1)open() open(SocketAddress)靜態方法用來創建SocketChannel對象,第二個重寫還會建立于遠程服務器的連接.
(2)socket()返回關聯的Socket對象
(3)isConnected()是否建立連接
(4)isConnectionPending判斷是否正在進行遠程連接
(5)connect() 建立遠程連接() 根據是否阻塞而不同
(6)finishConnect() 視圖完成遠程連接?
(7)read()讀取數據(這個應該是接數據)
(8)write()寫數據(這個是發送數據)
聲明:
public static int PORT = 8888; ServerSocketChannel serverChannel; ServerSocket serverSocket; Selector selector;
?
初始化:
// 1. 分配一個 ServerSocketChannel 文件描述符 serverChannel = ServerSocketChannel.open(); // 2. 從 ServerSocketChannel里獲取一個對于的 socket serverSocket = serverChannel.socket(); // 3. 生成一個 Selector selector = Selector.open(); // 4. 把 socket 綁定到端口上 serverSocket.bind(new InetSocketAddress(iport)); // 5. serverChannel 未非bolck serverChannel.configureBlocking(false); // 6. 通過Selector注冊ServerSocketChannel: 只能注冊 accept // 而SocketChannel可以注冊CONNENCT,READ,WRITE ; register -> validOps // 在各個子類實現不同 serverChannel.register(selector, SelectionKey.OP_ACCEPT);
?
開啟服務:
while (true) { try { // 獲得IO準備就緒的channel數量 int n = selector.select(); // 沒有channel準備就緒,繼續執行 if (n == 0) { continue; } // 用一個iterator返回Selector的selectedkeys Iterator it = selector.selectedKeys().iterator(); // 處理每一個SelectionKey while (it.hasNext()) { SelectionKey key = (SelectionKey) it.next(); // 判斷是否有新的連接到達 if (key.isAcceptable()) { // 返回SelectionKey的ServerSocketChannel ServerSocketChannel server = (ServerSocketChannel) key .channel(); System.out.println("有連接"); SocketChannel channel = server.accept(); registerChannel(selector, channel, SelectionKey.OP_READ); doWork(channel); } // 判斷是否有數據在此channel里需要讀取 if (key.isReadable()) { processData(key); } } // 刪除 selectedkeys it.remove(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
?
已有 0 人發表留言,猛擊->>這里<<-參與討論
ITeye推薦