Java NioSocket 的用法
来源:互联网 发布:吉他教学软件 编辑:程序博客网 时间:2024/06/05 11:13
说明
从 JDK1.4 开始, Java增加了新的 io 模式,nio(new IO), nio在底层采用了新的处理方式,极大地提高了IO的效率。
nio与原来的io对比:
要理解 NioSocket 的使用必须要理解三个概念:
- Buffer
- Channel
- Selector
类比快递:
- Buffer(要送的货物)
- Channel(送货员)
- Selector(中转站的分拣员)
NioSocket 中服务端的处理过程分5步:
- 创建 ServerSocketChannel 并设置相应参数
- 创建 Selector 并注册到 ServerSocketChannel 上。
- 调用 Selector 的 select 方法等待请求。
- Selector 接收请求后使用 selectedKeys 返回 SelectionKey 集合。
- 使用 SelectionKey 获取到 Channel、Selector 和操作类型并进行具体操作。
实例
NIOServer.java
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.ServerSocketChannel;import java.nio.channels.SocketChannel;import java.nio.charset.Charset;import java.util.Iterator;/** * @author : xiao * @date : 17/10/23 下午3:14 * @description : */public class NIOServer { public static void main(String[] args) throws Exception { // 创建ServerSocketChannel,监听8080端口 ServerSocketChannel ssc = ServerSocketChannel.open(); ssc.socket().bind(new InetSocketAddress(8080)); // 设置为非阻塞模式 ssc.configureBlocking(false); // 为ssc注册选择器 Selector selector = Selector.open(); ssc.register(selector, SelectionKey.OP_ACCEPT); // 创建处理器 Handler handler = new Handler(1024); while (true) { // 等待请求,每次等待阻塞3s,超过3s后线程继续向下运行,如果传入0或者不传参数将一直阻塞 if (selector.select(3000) == 0) { System.out.println("等待请求超时。。。"); continue; } System.out.println("处理请求。。。"); // 获取待处理的SelectionKey Iterator<SelectionKey> keyIter = selector.selectedKeys().iterator(); while (keyIter.hasNext()) { SelectionKey key = keyIter.next(); try { // 接收到连接请求时 if (key.isAcceptable()) { handler.handleAccept(key); } // 读数据 if (key.isReadable()) { handler.handleRead(key); } } catch (IOException ex) { keyIter.remove(); continue; } // 处理完后,从待处理的SelectionKey迭代器中移除当前所使用的key keyIter.remove(); } } } private static class Handler { private int bufferSize = 1024; private String localCharset = "UTF-8"; public Handler() { } public Handler(int bufferSize) { this(bufferSize, null); } public Handler(String LocalCharset) { this(-1, LocalCharset); } public Handler(int bufferSize, String localCharset) { if (bufferSize > 0) { this.bufferSize = bufferSize; } if (localCharset != null) { this.localCharset = localCharset; } } public void handleAccept(SelectionKey key) throws IOException { SocketChannel sc = ((ServerSocketChannel) key.channel()).accept(); sc.configureBlocking(false); sc.register(key.selector(), SelectionKey.OP_READ, ByteBuffer.allocate(bufferSize)); } public void handleRead(SelectionKey key) throws IOException { // 获取channel SocketChannel socketChannel = (SocketChannel) key.channel(); // 获取buffer并重置 ByteBuffer buffer = (ByteBuffer) key.attachment(); buffer.clear(); // 没有读到内容则关闭 if (socketChannel.read(buffer) == -1) { socketChannel.close(); } else { // 将buffer转换为读状态 buffer.flip(); // 将buffer中接收到的值按localCharset格式编码后保存到receivedString String receivedString = Charset.forName(localCharset).newDecoder().decode(buffer).toString(); System.out.println("received from client: " + receivedString); // 返回数据给客户端 StringBuilder sendString = new StringBuilder(); // 响应报文首行,200表示处理成功 sendString.append("HTTP/1.1 200 OK\r\n"); sendString.append("Content-Type:text/html;charset=" + localCharset + "\r\n"); // 报文头结束后加一个空行 sendString.append("\r\n"); sendString.append("<!DOCTYPE html>"); sendString.append("<html lang=\"en\">"); sendString.append("<head>"); sendString.append(" <meta charset=\"UTF-8\">"); sendString.append(" <title>Title</title>"); sendString.append("</head>"); sendString.append("<body>"); sendString.append(" <h4>hello world! </h4>"); sendString.append("</body>"); sendString.append("</html>"); buffer = ByteBuffer.wrap(sendString.toString().getBytes(localCharset)); socketChannel.write(buffer); // 关闭Socket socketChannel.close(); } } }}
测试
GET: http://localhost:8080
阅读全文
0 0
- Java NioSocket 的用法
- Java中NioSocket的用法--Spring MVC
- java中niosocket的实例使用
- java niosocket示例
- java NIOSocket 通信简要举例
- Java 网络编程之NioSocket
- NioSocket实现HTTP协议
- NioSocket相关知识
- java的static用法
- java-jar 的用法
- java的static用法
- java的static用法
- java的static用法
- java join的用法
- java volatile的用法
- Java Scanner的用法
- java StringTokenizer的用法
- Java native的用法
- HTML5 桌面通知:Notification API
- Alsa 遇上Android的音频延迟问题
- C语言 一元钱的兑换方案
- 时间戳密码
- Linux平台上SQLite数据库教程(一)——终端使用篇
- Java NioSocket 的用法
- eclipse查看快捷键及自主设置定义快捷键
- list集合导出Excel文件(二)
- 自己总结的web前端面试题之php
- C语言编程实现三子棋
- darknet_ros error shooting: undefined reference to `clReleaseMemObject@OPENCL_1.0'
- 利用spring AOP功能进行日志管理
- SSH框架搭建
- 341. Flatten Nested List Iterator