java 基础之--nio 网络编程

Posted 你所能做的,就是不断的学习

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 基础之--nio 网络编程相关的知识,希望对你有一定的参考价值。

在传统的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 网络编程的主要内容,如果未能解决你的问题,请参考以下文章

Java基础知识强化之网络编程笔记24:Android网络通信之 AndroidAsync(基于nio的异步通信库)

Java之NIO

Java基础知识强化之IO流笔记81:NIO之 DatagramChannel

NIO基础之Buffer

Java基础知识强化之IO流笔记79:NIO之 SocketChannel

java之socket编程(NIO)