java 基礎之--nio 網絡編程
阿新 • • 發佈:2018-10-04
ket byte readline oca pac efault rate mode accept
在傳統的Java 網絡編程中,對於客戶端的每次連接,對於服務器來說,都要創建一個新的線程與客戶端進行通訊,這種頻繁的線程的創建,對於服務器來說,是一種巨大的損耗,在Java 1.4 引入Java nio 引入了 selector channel buffer 對此操作進行重新的定義:
服務端:
package com.java.baseknowledge.net; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.nio.ByteBuffer;import java.nio.channels.SelectableChannel; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.HashMap; import java.util.Map; import java.util.Random; import java.util.Set;public class NioService { //store userMap public static Map<Integer,SocketChannel> userMap =new HashMap<>(); public static void main(String[] args) throws Exception { //selector object Selector selector =Selector.open(); //serversocketchannel object is listening client acceptServerSocketChannel serverSocket =ServerSocketChannel.open(); //Adjusts this channel‘s blocking mode. serverSocket.configureBlocking(false); serverSocket.bind(new InetSocketAddress(9099)); //在selector中register channel serverSocket.register(selector, SelectionKey.OP_ACCEPT); while(true) { //block method event listening,this method is perform when event is touch; selector.select(); //get selection-key set Set<SelectionKey> selectedKeys = selector.selectedKeys(); selectedKeys.forEach((keys->{ //judge selectionkey mode if(keys.isAcceptable()) { try { ServerSocketChannel channel = (ServerSocketChannel)keys.channel(); //obtain socketchannel SocketChannel accept = channel.accept(); accept.configureBlocking(false); //regist selector,listening read event accept.register(selector, SelectionKey.OP_READ); userMap.put(new Random().nextInt()*new Random().nextInt(), accept); } catch(Exception e ) { e.printStackTrace(); } } else if(keys.isReadable()) { //obtain socketchannel try { SocketChannel channel = (SocketChannel)keys.channel(); System.out.println(channel); ByteBuffer by = ByteBuffer.allocate(2048); channel.read(by); userMap.forEach((k,v)->{ by.rewind(); if(v!=channel) { try { v.write(by); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); } catch(Exception e) {} } selectedKeys.clear(); })); } } }
客戶端:
package com.java.baseknowledge.net; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; 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.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * chat client * @author Administrator * */ public class JavaNioClient { public static void main(String[] args) throws Exception { //建立Selector Selector selector =Selector.open(); SocketChannel socketChannel=SocketChannel.open(); //設置非阻塞 socketChannel.configureBlocking(false); socketChannel.register(selector, SelectionKey.OP_CONNECT); socketChannel.connect(new InetSocketAddress("127.0.0.1", 9099)); while(true) { selector.select(); Set<SelectionKey> setionkey =selector.selectedKeys(); for(SelectionKey kk :setionkey) { if(kk.isConnectable()) { //從selectionkey 獲取socketChannel SocketChannel socket=(SocketChannel)kk.channel(); //手動建立連接 if(socket.isConnectionPending()) { socket.finishConnect(); //寫數據 ByteBuffer byteB = ByteBuffer.allocate(1024); byteB.put((System.currentTimeMillis()+"連接ok").getBytes()); byteB.flip(); socket.write(byteB); //jdk1.5 線程池 ExecutorService exe =Executors.newSingleThreadExecutor(Executors.defaultThreadFactory()); exe.submit(new Thread() { @Override public void run() { while(true) { String msg=null; byteB.clear(); //標準鍵盤輸入 BufferedReader br =new BufferedReader(new InputStreamReader(System.in)); try { msg =br.readLine(); ByteBuffer bytec = ByteBuffer.allocate(1024); bytec.put(msg.getBytes()); bytec.flip(); socket.write(bytec); } catch (IOException e) { e.printStackTrace(); } } } }); } socket.register(selector, SelectionKey.OP_READ); } else if(kk.isReadable()) { //從selectionkey 獲取socketChannel SocketChannel socket=(SocketChannel)kk.channel(); ByteBuffer by =ByteBuffer.allocate(1024); int a=socket.read(by); //if(a>0) { String receive =new String(by.array()); System.out.println(receive); //} } setionkey.clear(); } } } }
java 基礎之--nio 網絡編程