Java NIO 經典實例代碼
作者:xm_king
最近一直在忙著JAVA NIO的知識,花了一下午的時間,總算寫出了一個可以運行的程序,廢話少說,上代碼!
最近一直在忙著JAVA NIO的知識,花了一下午的時間,總算寫出了一個可以運行的程序,廢話少說,上代碼!
Java代碼:
- import java.io.IOException;
- import java.net.InetSocketAddress;
- import java.net.ServerSocket;
- import java.nio.ByteBuffer;
- import java.nio.channels.SelectionKey;
- import java.nio.channels.Selector;
- import java.nio.channels.ServerSocketChannel;
- import java.nio.channels.SocketChannel;
- import java.util.Iterator;
- import java.util.Set;
- public class NIOServer {
- /*標識數字*/
- private int flag = 0;
- /*緩沖區大小*/
- private int BLOCK = 4096;
- /*接受數據緩沖區*/
- private ByteBuffer sendbuffer = ByteBuffer.allocate(BLOCK);
- /*發送數據緩沖區*/
- private ByteBuffer receivebuffer = ByteBuffer.allocate(BLOCK);
- private Selector selector;
- public NIOServer(int port) throws IOException {
- // 打開服務器套接字通道
- ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
- // 服務器配置為非阻塞
- serverSocketChannel.configureBlocking(false);
- // 檢索與此通道關聯的服務器套接字
- ServerSocket serverSocket = serverSocketChannel.socket();
- // 進行服務的綁定
- serverSocket.bind(new InetSocketAddress(port));
- // 通過open()方法找到Selector
- selector = Selector.open();
- // 注冊到selector,等待連接
- serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
- System.out.println("Server Start----8888:");
- }
- // 監聽
- private void listen() throws IOException {
- while (true) {
- // 選擇一組鍵,并且相應的通道已經打開
- selector.select();
- // 返回此選擇器的已選擇鍵集。
- Set<SelectionKey> selectionKeys = selector.selectedKeys();
- Iterator<SelectionKey> iterator = selectionKeys.iterator();
- while (iterator.hasNext()) {
- SelectionKey selectionKey = iterator.next();
- iterator.remove();
- handleKey(selectionKey);
- }
- }
- }
- // 處理請求
- private void handleKey(SelectionKey selectionKey) throws IOException {
- // 接受請求
- ServerSocketChannel server = null;
- SocketChannel client = null;
- String receiveText;
- String sendText;
- int count=0;
- // 測試此鍵的通道是否已準備好接受新的套接字連接。
- if (selectionKey.isAcceptable()) {
- // 返回為之創建此鍵的通道。
- server = (ServerSocketChannel) selectionKey.channel();
- // 接受到此通道套接字的連接。
- // 此方法返回的套接字通道(如果有)將處于阻塞模式。
- client = server.accept();
- // 配置為非阻塞
- client.configureBlocking(false);
- // 注冊到selector,等待連接
- client.register(selector, SelectionKey.OP_READ);
- } else if (selectionKey.isReadable()) {
- // 返回為之創建此鍵的通道。
- client = (SocketChannel) selectionKey.channel();
- //將緩沖區清空以備下次讀取
- receivebuffer.clear();
- //讀取服務器發送來的數據到緩沖區中
- count = client.read(receivebuffer);
- if (count > 0) {
- receiveText = new String( receivebuffer.array(),0,count);
- System.out.println("服務器端接受客戶端數據--:"+receiveText);
- client.register(selector, SelectionKey.OP_WRITE);
- }
- } else if (selectionKey.isWritable()) {
- //將緩沖區清空以備下次寫入
- sendbuffer.clear();
- // 返回為之創建此鍵的通道。
- client = (SocketChannel) selectionKey.channel();
- sendText="message from server--" + flag++;
- //向緩沖區中輸入數據
- sendbuffer.put(sendText.getBytes());
- //將緩沖區各標志復位,因為向里面put了數據標志被改變要想從中讀取數據發向服務器,就要復位
- sendbuffer.flip();
- //輸出到通道
- client.write(sendbuffer);
- System.out.println("服務器端向客戶端發送數據--:"+sendText);
- client.register(selector, SelectionKey.OP_READ);
- }
- }
- /**
- * @param args
- * @throws IOException
- */
- public static void main(String[] args) throws IOException {
- // TODO Auto-generated method stub
- int port = 8888;
- NIOServer server = new NIOServer(port);
- server.listen();
- }
- }
Java代碼:
- import java.io.IOException;
- import java.net.InetSocketAddress;
- import java.nio.ByteBuffer;
- import java.nio.channels.SelectionKey;
- import java.nio.channels.Selector;
- import java.nio.channels.SocketChannel;
- import java.util.Iterator;
- import java.util.Set;
- public class NIOClient {
- /*標識數字*/
- private static int flag = 0;
- /*緩沖區大小*/
- private static int BLOCK = 4096;
- /*接受數據緩沖區*/
- private static ByteBuffer sendbuffer = ByteBuffer.allocate(BLOCK);
- /*發送數據緩沖區*/
- private static ByteBuffer receivebuffer = ByteBuffer.allocate(BLOCK);
- /*服務器端地址*/
- private final static InetSocketAddress SERVER_ADDRESS = new InetSocketAddress(
- "localhost", 1111);
- public static void main(String[] args) throws IOException {
- // TODO Auto-generated method stub
- // 打開socket通道
- SocketChannel socketChannel = SocketChannel.open();
- // 設置為非阻塞方式
- socketChannel.configureBlocking(false);
- // 打開選擇器
- Selector selector = Selector.open();
- // 注冊連接服務端socket動作
- socketChannel.register(selector, SelectionKey.OP_CONNECT);
- // 連接
- socketChannel.connect(SERVER_ADDRESS);
- // 分配緩沖區大小內存
- Set<SelectionKey> selectionKeys;
- Iterator<SelectionKey> iterator;
- SelectionKey selectionKey;
- SocketChannel client;
- String receiveText;
- String sendText;
- int count=0;
- while (true) {
- //選擇一組鍵,其相應的通道已為 I/O 操作準備就緒。
- //此方法執行處于阻塞模式的選擇操作。
- selector.select();
- //返回此選擇器的已選擇鍵集。
- selectionKeys = selector.selectedKeys();
- //System.out.println(selectionKeys.size());
- iterator = selectionKeys.iterator();
- while (iterator.hasNext()) {
- selectionKey = iterator.next();
- if (selectionKey.isConnectable()) {
- System.out.println("client connect");
- client = (SocketChannel) selectionKey.channel();
- // 判斷此通道上是否正在進行連接操作。
- // 完成套接字通道的連接過程。
- if (client.isConnectionPending()) {
- client.finishConnect();
- System.out.println("完成連接!");
- sendbuffer.clear();
- sendbuffer.put("Hello,Server".getBytes());
- sendbuffer.flip();
- client.write(sendbuffer);
- }
- client.register(selector, SelectionKey.OP_READ);
- } else if (selectionKey.isReadable()) {
- client = (SocketChannel) selectionKey.channel();
- //將緩沖區清空以備下次讀取
- receivebuffer.clear();
- //讀取服務器發送來的數據到緩沖區中
- count=client.read(receivebuffer);
- if(count>0){
- receiveText = new String( receivebuffer.array(),0,count);
- System.out.println("客戶端接受服務器端數據--:"+receiveText);
- client.register(selector, SelectionKey.OP_WRITE);
- }
- } else if (selectionKey.isWritable()) {
- sendbuffer.clear();
- client = (SocketChannel) selectionKey.channel();
- sendText = "message from client--" + (flag++);
- sendbuffer.put(sendText.getBytes());
- //將緩沖區各標志復位,因為向里面put了數據標志被改變要想從中讀取數據發向服務器,就要復位
- sendbuffer.flip();
- client.write(sendbuffer);
- System.out.println("客戶端向服務器端發送數據--:"+sendText);
- client.register(selector, SelectionKey.OP_READ);
- }
- }
- selectionKeys.clear();
- }
- }
- }
個人感覺,JAVA NIO的操作時麻煩了不少,但是無疑這樣做效率會得到很大的提升。
原文鏈接:http://xm-king.iteye.com/blog/766330
【編輯推薦】
責任編輯:林師授
來源:
xm_king的博客