Java review--NIO例項:實現服務端和客戶端的簡單通訊
阿新 • • 發佈:2019-02-11
客戶端程式碼:
package nio; 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 =1; private int blockSize=4096; private ByteBuffer sendbuffer =ByteBuffer.allocate(blockSize);//傳送資料緩衝區 private ByteBuffer receivebuffer =ByteBuffer.allocate(blockSize);//接收資料緩衝區 private Selector selector;//選擇器 public NIOServer(int port) throws IOException{ ServerSocketChannel serverSocketChannel=ServerSocketChannel.open(); //設定是否組阻塞 serverSocketChannel.configureBlocking(false); //建立客戶端和服務端的socket.socket網路套接字,用來向網路傳送請求,或者應答請求。 ServerSocket serverSocket=serverSocketChannel.socket(); //繫結socket地址,IP埠 serverSocket.bind(new InetSocketAddress(port)); //開啟篩選器 selector=Selector.open(); // 將選擇器繫結到監聽通道,只有非阻塞通道才可以註冊選擇器.並在註冊過程中指出該通道可以進行Accept操作,返回key serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); System.out.println("Server start ->"+port); } //NIOServer的監聽事件 public void listen() throws IOException{ while(true){ selector.select(); Set<SelectionKey> selectionKeys=selector.selectedKeys(); Iterator<SelectionKey> itetor=selectionKeys.iterator(); while(itetor.hasNext()){ //負責多執行緒併發的安全的key SelectionKey selectionKey=itetor.next(); itetor.remove(); //業務邏輯 handleKey(selectionKey); } } } //業務邏輯 public void handleKey(SelectionKey selectionKey) throws IOException{ //服務端監聽通道 ServerSocketChannel server=null; SocketChannel client=null; String reciveText; String sendText; int count=0; if(selectionKey.isAcceptable()){ //服務端接收客戶端資訊 server=(ServerSocketChannel)selectionKey.channel(); client=server.accept(); client.configureBlocking(false); client.register(selector, selectionKey.OP_READ); }else if(selectionKey.isReadable()){ //服務端讀取客戶端資訊 client =(SocketChannel)selectionKey.channel(); count =client.read(receivebuffer); if(count>0){ reciveText =new String(receivebuffer.array(),0,count); System.out.println("服務端接收到客戶端的資訊:"+reciveText); client.register(selector,selectionKey.OP_WRITE); } }else if (selectionKey.isWritable()){ //服務端傳送資料給客戶端 sendbuffer.clear(); client=(SocketChannel)selectionKey.channel(); sendText="mag send to client:"+flag++; sendbuffer.put(sendText.getBytes()); sendbuffer.flip(); client.write(sendbuffer); System.out.println("服務端傳送資料給客戶端:"+sendText); } } public static void main(String[] args) throws IOException { int port =7080; NIOServer server =new NIOServer(port); server.listen(); } }
服務端程式碼:
package nio; 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 =1; private static int blockSize=4096; private static ByteBuffer sendbuffer =ByteBuffer.allocate(blockSize);//傳送資料緩衝區 private static ByteBuffer receivebuffer =ByteBuffer.allocate(blockSize);//接收資料緩衝區 //Socket地址:ip+埠 private final static InetSocketAddress serverAddress=new InetSocketAddress("127.0.0.1",7080); public static void main(String[] args) throws IOException { //開啟通道 SocketChannel socketChannel=SocketChannel.open(); //通道設定成非阻塞模式 socketChannel.configureBlocking(false); //開啟篩選器 Selector selector =Selector.open(); //註冊選擇器 socketChannel.register(selector, SelectionKey.OP_CONNECT); socketChannel.connect(serverAddress); Set<SelectionKey> selectionKeys; Iterator<SelectionKey> iterator; SelectionKey selectionKey; SocketChannel client; String receiveTest; String sendText; int count=0; while(true){ selectionKeys =selector.selectedKeys(); 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); }if(selectionKey.isReadable()){ client=(SocketChannel)selectionKey.channel(); receivebuffer.clear(); count=client.read(receivebuffer); if(count>0){ receiveTest =new String(receivebuffer.array(),0,count); System.out.println("客戶端接收到服務端的資料:"+receiveTest); client.register(selector,SelectionKey.OP_WRITE); } }if(selectionKey.isWritable()){ sendbuffer.clear(); client=(SocketChannel)selectionKey.channel(); sendText="Msg from client--->"+flag++; sendbuffer.put(sendText.getBytes()); sendbuffer.flip(); client.write(sendbuffer); System.out.println("客戶端傳送方資料給服務端:"+sendText); client.register(selector, SelectionKey.OP_READ); } } selectionKeys.clear(); } } }