Java NIO 同步非阻塞
一、server:
package org.windwant.nio; 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; /**
* ServerSocketChannel
*/
public class NIOServer {
/*标识数字*/
private int flag = 0;
/*缓冲区大小*/
private int BLOCK = 2048;
/*接受数据缓冲区*/
private ByteBuffer sendbuffer = ByteBuffer.allocate(BLOCK);
/*发送数据缓冲区*/
private ByteBuffer receivebuffer = ByteBuffer.allocate(BLOCK);
private Selector selector; public NIOServer(int port) throws IOException {
// 打开服务器套接字通道 ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
// 服务器配置为非阻塞 serverSocketChannel.configureBlocking(false);
// 检索与此通道关联的服务器套接字 ServerSocket serverSocket = serverSocketChannel.socket();
// 进行服务的绑定 serverSocket.bind(new InetSocketAddress(port));
// 通过open()方法找到Selector selector = Selector.open();
// 注册到selector,等待连接 serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("Server Start----8888:");
} // 监听 private void listen() throws IOException {
while (true) {
// 选择一组键,并且相应的通道已经打开 selector.select();
// 返回此选择器的已选择键集。 Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectionKeys.iterator();
while (iterator.hasNext()) {
SelectionKey selectionKey = iterator.next();
iterator.remove();
handleKey(selectionKey);
}
}
} // 处理请求 private void handleKey(SelectionKey selectionKey) throws IOException {
// 接受请求 ServerSocketChannel server = null;
SocketChannel client = null;
String receiveText;
String sendText;
int count=0;
// 测试此键的通道是否已准备好接受新的套接字连接。 if (selectionKey.isAcceptable()) {
// 返回为之创建此键的通道。 server = (ServerSocketChannel) selectionKey.channel();
// 接受到此通道套接字的连接。 // 此方法返回的套接字通道(如果有)将处于阻塞模式。 client = server.accept();
// 配置为非阻塞 client.configureBlocking(false);
// 注册到selector,等待连接 client.register(selector, SelectionKey.OP_READ);
} else if (selectionKey.isReadable()) {
// 返回为之创建此键的通道。 client = (SocketChannel) selectionKey.channel();
//将缓冲区清空以备下次读取 receivebuffer.clear();
//读取服务器发送来的数据到缓冲区中 count = client.read(receivebuffer);
if (count > 0) {
receiveText = new String( receivebuffer.array(),0,count);
System.out.println("服务器端接受客户端数据--:"+receiveText);
client.register(selector, SelectionKey.OP_WRITE);
}
} else if (selectionKey.isWritable()) {
//将缓冲区清空以备下次写入 sendbuffer.clear();
// 返回为之创建此键的通道。 client = (SocketChannel) selectionKey.channel(); sendText = "<h1>message from server: this is the test message!</h1>"; // sendText="message from server--" + flag++;
//向缓冲区中输入数据 sendbuffer.put(sendText.getBytes());
//将缓冲区各标志复位,因为向里面put了数据标志被改变要想从中读取数据发向服务器,就要复位 sendbuffer.flip();
//输出到通道 client.write(sendbuffer);
System.out.println("服务器端向客户端发送数据--:"+sendText);
client.register(selector, SelectionKey.OP_READ);
}
} /**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
int port = 8888;
NIOServer server = new NIOServer(port);
server.listen();
}
}
二、client:
package org.windwant.nio; 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; /**
* SocketChannel
*/
public class NIOClient {
/*标识数字*/
private static int flag = 0;
/*缓冲区大小*/
private static int BLOCK = 4096;
/*接受数据缓冲区*/
private static ByteBuffer sendbuffer = ByteBuffer.allocate(BLOCK);
/*发送数据缓冲区*/
private static ByteBuffer receivebuffer = ByteBuffer.allocate(BLOCK);
/*服务器端地址*/
private final static InetSocketAddress SERVER_ADDRESS = new InetSocketAddress(
"localhost", 8888); public static void main(String[] args) throws IOException {
// 打开socket通道 SocketChannel socketChannel = SocketChannel.open();
// 设置为非阻塞方式 socketChannel.configureBlocking(false);
// 打开选择器 Selector selector = Selector.open();
// 注册连接服务端socket动作 socketChannel.register(selector, SelectionKey.OP_CONNECT);
// 连接 socketChannel.connect(SERVER_ADDRESS);
// 分配缓冲区大小内存 Set<SelectionKey> selectionKeys;
Iterator<SelectionKey> iterator;
SelectionKey selectionKey;
SocketChannel client;
String receiveText;
String sendText;
int count=0; while (true) {
//选择一组键,其相应的通道已为 I/O 操作准备就绪。 //此方法执行处于阻塞模式的选择操作。 selector.select();
//返回此选择器的已选择键集。 selectionKeys = selector.selectedKeys();
//System.out.println(selectionKeys.size()); iterator = selectionKeys.iterator();
while (iterator.hasNext()) {
selectionKey = iterator.next();
if (selectionKey.isConnectable()) {
System.out.println("client connect");
client = (SocketChannel) selectionKey.channel();
// 判断此通道上是否正在进行连接操作。 // 完成套接字通道的连接过程。 if (client.isConnectionPending()) {
client.finishConnect();
System.out.println("完成连接!");
sendbuffer.clear();
sendbuffer.put("Hello,Server".getBytes());
sendbuffer.flip();
client.write(sendbuffer);
}
client.register(selector, SelectionKey.OP_READ);
} else if (selectionKey.isReadable()) {
client = (SocketChannel) selectionKey.channel();
//将缓冲区清空以备下次读取 receivebuffer.clear();
//读取服务器发送来的数据到缓冲区中 count=client.read(receivebuffer);
if(count>0){
receiveText = new String( receivebuffer.array(),0,count);
System.out.println("客户端接受服务器端数据--:"+receiveText);
client.register(selector, SelectionKey.OP_WRITE);
} } else if (selectionKey.isWritable()) {
sendbuffer.clear();
client = (SocketChannel) selectionKey.channel();
sendText = "message from client--" + (flag++);
sendbuffer.put(sendText.getBytes());
//将缓冲区各标志复位,因为向里面put了数据标志被改变要想从中读取数据发向服务器,就要复位 sendbuffer.flip();
client.write(sendbuffer);
System.out.println("客户端向服务器端发送数据--:"+sendText);
client.register(selector, SelectionKey.OP_READ);
}
}
selectionKeys.clear();
}
}
}
项目地址:https://github.com/windwant/windwant-service/tree/master/io-service
Java NIO 同步非阻塞的更多相关文章
- 【转载】高性能IO设计 & Java NIO & 同步/异步 阻塞/非阻塞 Reactor/Proactor
开始准备看Java NIO的,这篇文章:http://xly1981.iteye.com/blog/1735862 里面提到了这篇文章 http://xmuzyq.iteye.com/blog/783 ...
- Java NIO Socket 非阻塞通信
相对于非阻塞通信的复杂性,通常客户端并不需要使用非阻塞通信以提高性能,故这里只有服务端使用非阻塞通信方式实现 客户端: package com.test.client; import java.io. ...
- java nio实现非阻塞Socket通信实例
服务器 package com.java.xiong.Net17; import java.io.IOException; import java.net.InetSocketAddress; imp ...
- JAVA NIO使用非阻塞模式实现高并发服务器
参考:http://blog.csdn.net/zmx729618/article/details/51860699 https://zhuanlan.zhihu.com/p/23488863 ht ...
- 如何解读 Java IO、NIO 中的同步阻塞与同步非阻塞?
原文链接:如何解读 Java IO.NIO 中的同步阻塞与同步非阻塞? 一.前言 最近刚读完一本书:<Netty.Zookeeper.Redis 并发实战>,个人觉得 Netty 部分是写 ...
- NIO【同步非阻塞io模型】关于 NIO socket 的详细总结【Java客户端+Java服务端 + 业务层】【可以客户端间发消息】
1.前言 以前使用 websocket来实现双向通信,如今深入了解了 NIO 同步非阻塞io模型 , 优势是 处理效率很高,吞吐量巨大,能很快处理大文件,不仅可以 做 文件io操作, 还可以做sock ...
- 同步异步阻塞非阻塞Reactor模式和Proactor模式 (目前JAVA的NIO就属于同步非阻塞IO)
在高性能的I/O设计中,有两个比较著名的模式Reactor和Proactor模式,其中Reactor模式用于同步I/O,而Proactor运用于异步I/O操作. 在比较这两个模式之前,我们首先的搞明白 ...
- java的高并发IO原理,阻塞BIO同步非阻塞NIO,异步非阻塞AIO
原文地址: IO读写的基础原理 大家知道,用户程序进行IO的读写,依赖于底层的IO读写,基本上会用到底层的read&write两大系统调用.在不同的操作系统中,IO读写的系统调用的名称可能不完 ...
- IO通信模型(二)同步非阻塞模式NIO(NonBlocking IO)
同步非阻塞模式(NonBlocking IO) 在非阻塞模式中,发出Socket的accept()和read()操作时,如果内核中的数据还没有准备好,那么它并不会阻塞用户进程,而是立刻返回一个信息.也 ...
随机推荐
- .NET使用ZXing.NET生成中间带图片的二维码
很久之前就有写这样的代码了,只是一直没记录下来,偶然想写成博客. 把之前的代码封装成函数,以方便理解以及调用. 基于开源的 ZXing.NET 组件,代码如下: 先添加对ZXing.NET的引用,然后 ...
- 不可或缺 Windows Native 系列文章索引
[源码下载] 不可或缺 Windows Native 系列文章索引 作者:webabcd 1.不可或缺 Windows Native (1) - C 语言: hello c 介绍不可或缺 Window ...
- 再探OAuth2
原文: http://www.cnblogs.com/Irving/p/4134629.html web:http://oauth.net/2/ rfc: http://tools.ietf.org/ ...
- MyEclipse 不能将WAR包导出的解决方法
不能导出WAR包的原因是破解没有完全导致的. 解决办法: 找到MyEclipse安装目录下MyEclipse\Common\plugins文件夹中的com.genuitec.eclipse.expor ...
- 【转】正确设置php-fpm子进程用户,提高网站安全性防挂马
原文地址:http://www.myhack58.com/Article/60/61/2013/37209.htm 根据生产环境不断反馈,发现不断有 PHP网站被挂木马,绝大部分原因是因为权限设置不合 ...
- js的一些属性
js attribute(): setAttribute():element.setAttribute(name,balue) getAttribute():element.getAttribute( ...
- Flexslider - 响应式的 jQuery 内容滚动插件
FlexSlider 是一款轻量的响应式 jQuery 内容滚动插件,能够帮助你在项目轻松的创建漂亮的内容滚动效果.这款插件曾经连续多年入选 WDL 的年度最佳 jQuery 插件,值得大家在网站开发 ...
- javascript中关于数组的一些鄙视题
一.判断一个数组中是否有相同的元素 /* * 判断数组中是否有相同的元素的代码 */ // 方案一 function isRepeat1(arrs) { if(arrs.length > 0) ...
- css布局模式
css布局模型在网页中,元素有三种布局模型: 流动模型(Flow) 浮动模型 (Float) 层模型(Layer) 流动Flow模型(一): 流动(Flow)是默认的网页布局模式.也就是说网页在默认状 ...
- [deviceone开发]-do_FrameAnimtionView的简单动画示例
一.简介 do_FrameAnimtionView组件是用加载GIF动态图片和加载一系列图片形成动画效果的展示组件,这个示例直观的展示组件基本的使用方式.适合初学者. 二.效果图 三.相关下载 htt ...