Nio的基础与使用
来源:互联网 发布:收费软件炒股最好 编辑:程序博客网 时间:2024/06/08 10:33
Nio的介绍
nio是指jdk1.4 及以上版本里提供的新api(New IO) ,为所有的原始类型(boolean类型除外)提供缓存支持的数据容器,使用它可以提供非阻塞式的高伸缩性网络
nio里面最重要的三个对象
- Buffer 缓存区
- channel 通道
- selector 选择器
nio的常用方法
- buffer.flip()改变position和limit的值,就是传统说的把写变成读,把读变成写。
- buffer.clear()清除buffer,buffer.compact()也是清除,只是清除已读
- Selector.select()监听注册通道.
- Selector.selectKeys获取事件中的SelectKey
- channel.register()把通道注册到Selector,并指定你要监听的事件
Nio的使用
使用nio操作文件
拷贝a.txt的内容到b.txt
import java.io.*;import java.nio.ByteBuffer;import java.nio.channels.FileChannel;/** * Created by tannent on 11/14/17. */public class CopyFile {public static void main(String []args) throws IOException { //打开文件输入流 FileInputStream inputStream=new FileInputStream(new File("D:\\a.txt")); //从输入流中获取通道 FileChannel inputChannel= inputStream.getChannel(); //打开文件输出流 FileOutputStream outputStream=new FileOutputStream(new File("D:\\b.txt")); //从输出流获取通道 FileChannel outChannel=outputStream.getChannel(); //创建一个字节缓存区 ByteBuffer buffer=ByteBuffer.allocate(1024); while(true){ int n=inputChannel.read(buffer); if(n<=0){ break; } //使读模式改成写模式,其实就是改变Position,Limit的值, // 把position的值赋给limit,然后把position设置为0 buffer.flip(); //向输出通道写入 outChannel.write(buffer); //清空缓存区 buffer.clear(); } outChannel.close(); inputChannel.close(); outputStream.close(); inputStream.close(); }}
使用Nio进行网络通信
简单的使用,通过客户端发送信息,服务端回消息给客户端
客户端代码
import sun.beans.editors.ByteEditor;import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.SocketChannel;/** * Created by tannent on 11/14/17. */public class NioClient { public static void main(String[] args) throws IOException { SocketChannel socketChannel=SocketChannel.open(); socketChannel.connect(new InetSocketAddress("localhost",8088)); ByteBuffer byteBuffer= ByteBuffer.wrap("连接服务器".getBytes()); socketChannel.write(byteBuffer); socketChannel.socket().shutdownOutput(); ByteBuffer outBuffer=ByteBuffer.allocate(1024); byte[] bytes; int n=0; String str=""; while((n=socketChannel.read(outBuffer))>0){ outBuffer.flip(); bytes=new byte[n]; outBuffer.get(bytes); str+=new String(bytes); outBuffer.clear(); } System.out.println(str); socketChannel.socket().shutdownInput(); socketChannel.socket().close(); socketChannel.close(); }}
服务端代码
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;/** * Created by tannent on 11/14/17. */public class Server {public static void main(String[] args) throws IOException { Selector selector=Selector.open(); ServerSocketChannel serverSocketChannel=ServerSocketChannel.open(); ServerSocket serverSocket= serverSocketChannel.socket(); serverSocket.bind(new InetSocketAddress(8088)); serverSocketChannel.configureBlocking(false); serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); while(true){ int num=selector.select(); if(num>0){ Set<SelectionKey> selectionKeys=selector.selectedKeys(); Iterator<SelectionKey> selectionKeyIterator=selectionKeys.iterator(); while (selectionKeyIterator.hasNext()){ SelectionKey selectionKey=selectionKeyIterator.next(); if(selectionKey.isAcceptable()){ ServerSocketChannel serverSocketChannel1= (ServerSocketChannel) selectionKey.channel(); SocketChannel socketChannel=serverSocketChannel1.accept(); socketChannel.configureBlocking(false); socketChannel.register(selector,SelectionKey.OP_READ); selectionKeyIterator.remove(); }else if(selectionKey.isReadable()){ ByteBuffer buffer=ByteBuffer.allocate(1024); SocketChannel socketChannel= (SocketChannel) selectionKey.channel(); int n=0; byte[] bytes; String str="服务器响应,你的连接信息是 "; while ((n=socketChannel.read(buffer))>0){ buffer.flip(); bytes=new byte[n]; buffer.get(bytes); str+=new String(bytes); buffer.clear(); } socketChannel.write(ByteBuffer.wrap(str.getBytes())); socketChannel.close(); selectionKeyIterator.remove(); } } } } }}
案例2 客户端通过服务器转发数据进行客户端之间的通讯
客户端代码
import com.sun.org.apache.bcel.internal.generic.Select;import sun.beans.editors.ByteEditor;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;/** * Created by tannent on 11/14/17. */public class NioClient {SocketChannel socketChannel;public NioClient(String num) { Selector selector= null; try { selector = Selector.open(); socketChannel=SocketChannel.open(); socketChannel.connect(new InetSocketAddress("localhost",8088)); socketChannel.configureBlocking(false); socketChannel.register(selector, SelectionKey.OP_READ); ClientThread clientThread=new ClientThread(); clientThread.setSelector(selector); new Thread(clientThread).start(); sendMsg(MessageType.LOGIN+"#"+num+"#0#你好"); } catch (IOException e) { e.printStackTrace(); }}public void sendMsg(String msg){ try { socketChannel.write(ByteBuffer.wrap(msg.getBytes())); } catch (Exception e) { e.printStackTrace(); } }}
客户端接受消息的线程
import java.io.IOException;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;/** * Created by tannent on 11/14/17. */public class ClientThread implements Runnable {public static int i=0;private Selector selector;public void setSelector(Selector selector) { this.selector = selector;}@Overridepublic void run() { try { while (selector.select()>0) { Set<SelectionKey> selectionKeySet = selector.selectedKeys(); Iterator<SelectionKey> selectionKeyIterator = selectionKeySet.iterator(); while (selectionKeyIterator.hasNext()) { SelectionKey key = selectionKeyIterator.next(); if (key.isReadable()) { SocketChannel socketChannel = (SocketChannel) key.channel(); ByteBuffer outBuffer = ByteBuffer.allocate(1024); byte[] bytes; int n = 0; String str = ""; while ((n = socketChannel.read(outBuffer)) > 0) { outBuffer.flip(); bytes = new byte[n]; outBuffer.get(bytes); str += new String(bytes); outBuffer.clear(); } // key.interestOps(SelectionKey.OP_READ); System.out.println(str); selector.selectedKeys().remove(key); } } } } catch (IOException e) { e.printStackTrace(); }}}
服务端代码
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;/** * Created by tannent on 11/14/17. */public class Server {public static int i=0;public static void main(String[] args) throws IOException { Selector selector=Selector.open(); ServerSocketChannel serverSocketChannel=ServerSocketChannel.open(); ServerSocket serverSocket= serverSocketChannel.socket(); serverSocket.bind(new InetSocketAddress(8088)); serverSocketChannel.configureBlocking(false); serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); while(true){ int num=selector.select(); if(num>0){ Set<SelectionKey> selectionKeys=selector.selectedKeys(); Iterator<SelectionKey> selectionKeyIterator=selectionKeys.iterator(); while (selectionKeyIterator.hasNext()){ SelectionKey selectionKey=selectionKeyIterator.next(); if(selectionKey.isAcceptable()){ ServerSocketChannel serverSocketChannel1= (ServerSocketChannel) selectionKey.channel(); SocketChannel socketChannel=serverSocketChannel1.accept(); socketChannel.configureBlocking(false); socketChannel.register(selector,SelectionKey.OP_READ|SelectionKey.OP_WRITE,ByteBuffer.allocate(1024)); selectionKeyIterator.remove(); }else if(selectionKey.isReadable()){ ByteBuffer buffer=(ByteBuffer)selectionKey.attachment(); buffer.clear(); SocketChannel socketChannel= (SocketChannel) selectionKey.channel(); int n=0; byte[] bytes; String str=""; while ((n=socketChannel.read(buffer))>0){ if(n==-1){ socketChannel.close(); } buffer.flip(); bytes=new byte[n]; buffer.get(bytes); str+=new String(bytes); buffer.clear(); } System.out.println(str); String[] strings=str.split("#"); for (String str1:strings ) { System.out.println(str1); } if(strings[0].equals("1")){ SocketChannelManage.addSocketChannel(strings[1],socketChannel); }else { System.out.println("发送消息"); SocketChannelManage.getSocketChannel(strings[2]).write(ByteBuffer.wrap((strings[1]+"发来消息"+strings[3]).getBytes())); System.out.println("发送消息"); } // selectionKey.interestOps(SelectionKey.OP_READ); selectionKeyIterator.remove(); } } } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } }}}
发送消息的类型
public final class MessageType {private MessageType(){}public static final int LOGIN=1;public static final int MESSAGE=2;}
服务端channel管理的类
import java.nio.channels.SocketChannel;import java.util.HashMap;import java.util.Map;public class SocketChannelManage {private static Map<String,SocketChannel> socketChannelMap=new HashMap<>();private SocketChannelManage(){}public static void addSocketChannel(String key,SocketChannel socketChannel){ if(socketChannelMap.containsKey(key)) return; socketChannelMap.put(key,socketChannel);}public static void removeSocketChannel(String key){ socketChannelMap.remove(key);}public static SocketChannel getSocketChannel(String key){ return socketChannelMap.get(key);}}
阅读全文
0 0
- Nio的基础与使用
- NIO与IO的区别与使用
- java nio与tomcat 6 中nio的使用
- java nio与tomcat 6 中nio的使用
- 使用 XML: 与 Java NIO 的较量
- java中io与nio的使用
- Java NIO:IO与NIO的区别
- Java NIO:IO与NIO的区别
- NIO的使用
- NIO的使用
- NIO的使用
- Java NIO的使用
- java nio的使用
- NIO的使用心得
- NIO的简单使用
- NIO使用的例子
- 流与文件:NIO.2的介绍和使用
- SSL + Socket NIO 原理 与 SSLEngine + Naga SSLSocket 的使用
- Java语言基础
- C++源文件的后缀名问题(关于.h,.hh,.hpp,hxx . .cpp,.c,.cc,.cxx 一些小知识)
- jquery timeline插件展示操作记录
- 给系统APP添加默认权限,不再弹框
- 深入解析Redis使用场景分析
- Nio的基础与使用
- spring-boot--整合thymeleaf模板
- Java基础(十四) ---- classLoader详细解释及自定义classLoader
- Go语言中append函数返回值必须有变量接收的原因探究
- Android 关于事件分发 dispatchTouchEvent
- leetcode 349. Intersection of Two Arrays
- jQuery让div里的东西来回滚动显示
- jquery 使用html video
- (通用)深度学习环境搭建:tensorflow安装教程及常见错误解决