1. 程式人生 > >java 基礎之--nio 網絡編程

java 基礎之--nio 網絡編程

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 accept
ServerSocketChannel 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 網絡編程