Java NIO 經(jīng)典實(shí)例代碼
作者:xm_king
最近一直在忙著JAVA NIO的知識,花了一下午的時(shí)間,總算寫出了一個(gè)可以運(yùn)行的程序,廢話少說,上代碼!
最近一直在忙著JAVA NIO的知識,花了一下午的時(shí)間,總算寫出了一個(gè)可以運(yùn)行的程序,廢話少說,上代碼!
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 {
- /*標(biāo)識數(shù)字*/
- private int flag = 0;
- /*緩沖區(qū)大小*/
- private int BLOCK = 4096;
- /*接受數(shù)據(jù)緩沖區(qū)*/
- private ByteBuffer sendbuffer = ByteBuffer.allocate(BLOCK);
- /*發(fā)送數(shù)據(jù)緩沖區(qū)*/
- private ByteBuffer receivebuffer = ByteBuffer.allocate(BLOCK);
- private Selector selector;
- public NIOServer(int port) throws IOException {
- // 打開服務(wù)器套接字通道
- ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
- // 服務(wù)器配置為非阻塞
- serverSocketChannel.configureBlocking(false);
- // 檢索與此通道關(guān)聯(lián)的服務(wù)器套接字
- ServerSocket serverSocket = serverSocketChannel.socket();
- // 進(jìn)行服務(wù)的綁定
- serverSocket.bind(new InetSocketAddress(port));
- // 通過open()方法找到Selector
- selector = Selector.open();
- // 注冊到selector,等待連接
- serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
- System.out.println("Server Start----8888:");
- }
- // 監(jiān)聽
- private void listen() throws IOException {
- while (true) {
- // 選擇一組鍵,并且相應(yīng)的通道已經(jīng)打開
- 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;
- // 測試此鍵的通道是否已準(zhǔn)備好接受新的套接字連接。
- if (selectionKey.isAcceptable()) {
- // 返回為之創(chuàng)建此鍵的通道。
- server = (ServerSocketChannel) selectionKey.channel();
- // 接受到此通道套接字的連接。
- // 此方法返回的套接字通道(如果有)將處于阻塞模式。
- client = server.accept();
- // 配置為非阻塞
- client.configureBlocking(false);
- // 注冊到selector,等待連接
- client.register(selector, SelectionKey.OP_READ);
- } else if (selectionKey.isReadable()) {
- // 返回為之創(chuàng)建此鍵的通道。
- client = (SocketChannel) selectionKey.channel();
- //將緩沖區(qū)清空以備下次讀取
- receivebuffer.clear();
- //讀取服務(wù)器發(fā)送來的數(shù)據(jù)到緩沖區(qū)中
- count = client.read(receivebuffer);
- if (count > 0) {
- receiveText = new String( receivebuffer.array(),0,count);
- System.out.println("服務(wù)器端接受客戶端數(shù)據(jù)--:"+receiveText);
- client.register(selector, SelectionKey.OP_WRITE);
- }
- } else if (selectionKey.isWritable()) {
- //將緩沖區(qū)清空以備下次寫入
- sendbuffer.clear();
- // 返回為之創(chuàng)建此鍵的通道。
- client = (SocketChannel) selectionKey.channel();
- sendText="message from server--" + flag++;
- //向緩沖區(qū)中輸入數(shù)據(jù)
- sendbuffer.put(sendText.getBytes());
- //將緩沖區(qū)各標(biāo)志復(fù)位,因?yàn)橄蚶锩鎝ut了數(shù)據(jù)標(biāo)志被改變要想從中讀取數(shù)據(jù)發(fā)向服務(wù)器,就要復(fù)位
- sendbuffer.flip();
- //輸出到通道
- client.write(sendbuffer);
- System.out.println("服務(wù)器端向客戶端發(fā)送數(shù)據(jù)--:"+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 {
- /*標(biāo)識數(shù)字*/
- private static int flag = 0;
- /*緩沖區(qū)大小*/
- private static int BLOCK = 4096;
- /*接受數(shù)據(jù)緩沖區(qū)*/
- private static ByteBuffer sendbuffer = ByteBuffer.allocate(BLOCK);
- /*發(fā)送數(shù)據(jù)緩沖區(qū)*/
- private static ByteBuffer receivebuffer = ByteBuffer.allocate(BLOCK);
- /*服務(wù)器端地址*/
- 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();
- // 設(shè)置為非阻塞方式
- socketChannel.configureBlocking(false);
- // 打開選擇器
- Selector selector = Selector.open();
- // 注冊連接服務(wù)端socket動(dòng)作
- socketChannel.register(selector, SelectionKey.OP_CONNECT);
- // 連接
- socketChannel.connect(SERVER_ADDRESS);
- // 分配緩沖區(qū)大小內(nèi)存
- Set<SelectionKey> selectionKeys;
- Iterator<SelectionKey> iterator;
- SelectionKey selectionKey;
- SocketChannel client;
- String receiveText;
- String sendText;
- int count=0;
- while (true) {
- //選擇一組鍵,其相應(yīng)的通道已為 I/O 操作準(zhǔn)備就緒。
- //此方法執(zhí)行處于阻塞模式的選擇操作。
- 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();
- // 判斷此通道上是否正在進(jìn)行連接操作。
- // 完成套接字通道的連接過程。
- 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();
- //將緩沖區(qū)清空以備下次讀取
- receivebuffer.clear();
- //讀取服務(wù)器發(fā)送來的數(shù)據(jù)到緩沖區(qū)中
- count=client.read(receivebuffer);
- if(count>0){
- receiveText = new String( receivebuffer.array(),0,count);
- System.out.println("客戶端接受服務(wù)器端數(shù)據(jù)--:"+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());
- //將緩沖區(qū)各標(biāo)志復(fù)位,因?yàn)橄蚶锩鎝ut了數(shù)據(jù)標(biāo)志被改變要想從中讀取數(shù)據(jù)發(fā)向服務(wù)器,就要復(fù)位
- sendbuffer.flip();
- client.write(sendbuffer);
- System.out.println("客戶端向服務(wù)器端發(fā)送數(shù)據(jù)--:"+sendText);
- client.register(selector, SelectionKey.OP_READ);
- }
- }
- selectionKeys.clear();
- }
- }
- }
個(gè)人感覺,JAVA NIO的操作時(shí)麻煩了不少,但是無疑這樣做效率會(huì)得到很大的提升。
原文鏈接:http://xm-king.iteye.com/blog/766330
【編輯推薦】
責(zé)任編輯:林師授
來源:
xm_king的博客