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基础知识强化之IO流笔记81:NIO之 DatagramChannel