zhangxl_blog
路漫漫其修远兮,吾将上下而求索!
BlogJava
首页
新随笔
新文章
联系
聚合
管理
posts - 28, comments - 15, trackbacks - 0
Java NIO Demo
在读Amoeba源码的时候,里面采用java NIO进行通信管理,以前也了解过一些关于这方面的知识但是都不太系统,最近两天抽时间对这块进行一下扫盲。我主要参考以下两篇文章,个人认为这两篇文章还是不错的入门级文章,讲的比较通俗易懂。
1.
http://www.ibm.com/developerworks/cn/education/java/j-nio/section11.html
比较系统的讲述了Channel(通道)、Buffer(缓冲区)、position,limit,
capacity
in buffer等;其示例代码在:
http://code.google.com/p/astudy/source/browse/trunk/applications/astudy/nio/MultiPortEcho.java?spec=svn141&r=141
下
2.
http://tutorials.jenkov.com/java-nio/index.html
这个站点也是一个不错的入门级别介绍,虽然是e文,但讲解的比较细致。
3.我的demo
这个小例子,模拟了一个echo服务,客户端向echo服务器发送一段信息,echo收到信息后,返回给客户端,然后,连接关闭。代码如下:
/** */
/**
************************************
*/
客户端代码:
package
com.zxl.channel;
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.nio.charset.Charset;
import
java.util.Set;
public
class
EchoClient
{
/** */
/**
*
@param
args
*
@throws
IOException
*/
public
static
void
main(String[] args)
throws
IOException
{
SocketChannel channel
=
SocketChannel.open();
channel.configureBlocking(
false
);
InetSocketAddress s
=
new
InetSocketAddress(
"
localhost
"
,
2000
);
channel.connect(s);
Selector selector
=
Selector.open();
channel.register(selector, SelectionKey.OP_CONNECT
|
SelectionKey.OP_READ);
Charset charset
=
Charset.forName(
"
GBK
"
);
boolean
isFinished
=
false
;
while
(
!
isFinished)
{
int
num
=
selector.select();
if
(num
>
0
)
{
Set
<
SelectionKey
>
keys
=
selector.selectedKeys();
for
(SelectionKey k:keys)
{
if
(k.isConnectable())
{
SocketChannel sc
=
(SocketChannel) k.channel();
sc.configureBlocking(
false
);
sc.finishConnect();
sc.register(selector, SelectionKey.OP_READ);
ByteBuffer echoBuffer
=
ByteBuffer.allocate(
1024
);
ByteBuffer info
=
charset.encode(
"
好了克隆技术杜洛克防水堵漏开发!
"
);
echoBuffer.put(info);
echoBuffer.flip();
sc.write(echoBuffer);
echoBuffer.clear();
}
else
if
(k.isValid()
&&
k.isReadable())
{
ByteBuffer echoBuffer
=
ByteBuffer.allocate(
1024
);
SocketChannel sc
=
(SocketChannel) k.channel();
sc.read(echoBuffer);
echoBuffer.flip();
System.out.println(
"
echo server return:
"
+
charset.decode(echoBuffer).toString());
echoBuffer.clear();
isFinished
=
true
;
k.cancel();
sc.close();
selector.close();
}
}
}
}
}
}
/** */
/**
******************************************
*/
服务端代码:
package
com.zxl.channel;
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.nio.charset.Charset;
import
java.util.Iterator;
import
java.util.Set;
public
class
MultiPortEchoServer
{
private
Charset charset
=
Charset.forName(
"
GBK
"
);
private
int
[] ports;
/** */
/**
*
@param
args
*/
public
static
void
main(String[] args)
{
int
[] ps
=
{
2000
,
2001
}
;
//
默认监听2000,2001端口
new
MultiPortEchoServer(ps);
}
public
MultiPortEchoServer(
int
[] ports)
{
this
.ports
=
ports;
try
{
go();
}
catch
(IOException e)
{
//
TODO Auto-generated catch block
e.printStackTrace();
}
}
public
void
go()
throws
IOException
{
Selector selector
=
Selector.open();
for
(
int
i
=
0
;i
<
ports.length;i
++
)
{
ServerSocketChannel channel
=
ServerSocketChannel.open();
channel.configureBlocking(
false
);
ServerSocket socket
=
channel.socket();
InetSocketAddress address
=
new
InetSocketAddress(
"
localhost
"
,ports[i]);
socket.bind(address);
//
注册接受连接事件
channel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println(
"
Going to listen on
"
+
ports[i] );
}
while
(
true
)
{
int
num
=
selector.select();
Set
<
SelectionKey
>
keys
=
selector.selectedKeys();
Iterator
<
SelectionKey
>
iter
=
keys.iterator();
while
(iter.hasNext())
{
SelectionKey key
=
iter.next();
if
((key.readyOps()
&
SelectionKey.OP_ACCEPT)
==
SelectionKey.OP_ACCEPT)
{
ServerSocketChannel ssc
=
(ServerSocketChannel) key.channel();
SocketChannel sc
=
ssc.accept();
sc.configureBlocking(
false
);
sc.register(selector, SelectionKey.OP_READ);
iter.remove();
}
else
if
((key.readyOps()
&
SelectionKey.OP_READ)
==
SelectionKey.OP_READ)
{
SocketChannel sc
=
(SocketChannel) key.channel();
if
(
!
sc.isOpen())
{
selector
=
Selector.open();
}
else
{
ByteBuffer echoBuffer
=
ByteBuffer.allocate(
1024
);
//
int x = sc.read(echoBuffer);
while
(sc.read(echoBuffer)
>
0
)
{
System.out.println(
"
Echoed
"
+
charset.decode(echoBuffer).toString()
+
"
from
"
+
sc.socket().getInetAddress().getHostAddress() );
echoBuffer.flip();
sc.write(echoBuffer);
echoBuffer.clear();
}
iter.remove();
/**/
/*
返回信息后关闭连接
*/
key.cancel();
sc.close();
}
}
}
keys.clear();
}
}
}
posted on 2011-06-30 16:24
zhangxl
阅读(2781)
评论(1)
编辑
收藏
所属分类:
java concurrency
FeedBack:
#
re: Java NIO Demo
2014-11-24 09:47 |
zuidaima
java demo学习实例教程源代码下载:
http://zuidaima.com/share/kjava-p1-s1.htm
回复
更多评论
新用户注册
刷新评论列表
只有注册用户
登录
后才能发表评论。
网站导航:
博客园
IT新闻
知识库
C++博客
博问
相关文章:
使用java nio 实现 Ping
Java NIO Demo
<
2011年6月
>
日
一
二
三
四
五
六
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1
2
3
4
5
6
7
8
9
常用链接
我的随笔
我的评论
我的参与
最新评论
留言簿
(1)
给我留言
查看公开留言
查看私人留言
随笔分类
(17)
arithmetics(3)
C/C++(1)
Cache
DB(1)
IOC/AOP(2)
java concurrency(2)
java 多线程
JDK(1)
JVM(1)
Linux(1)
nosql(5)
Performance
随笔档案
(28)
2014年7月 (3)
2014年5月 (1)
2014年4月 (1)
2013年6月 (1)
2013年4月 (2)
2013年3月 (1)
2012年8月 (1)
2012年5月 (1)
2012年2月 (6)
2012年1月 (1)
2011年10月 (1)
2011年9月 (1)
2011年6月 (2)
2009年8月 (3)
2008年5月 (1)
2006年4月 (2)
文章分类
(30)
AJAX
common(3)
DB(3)
java tools(1)
JAVA 基础文章(1)
java 并发(3)
JDBC(1)
linux(3)
ORM(包括hibernate等)(2)
Spring(6)
SWT、SWING、AWT(2)
web(2)
web service
优化(2)
版本控制(1)
文章档案
(30)
2013年4月 (1)
2013年3月 (1)
2012年1月 (2)
2011年12月 (1)
2011年11月 (1)
2011年8月 (2)
2011年7月 (1)
2011年6月 (4)
2011年4月 (3)
2009年8月 (4)
2008年6月 (1)
2008年4月 (1)
2007年3月 (2)
2006年12月 (1)
2006年10月 (2)
2006年8月 (1)
2006年6月 (1)
2006年4月 (1)
相册
my picture
收藏夹
(2)
我的关注(2)
hibernate
java基础
serialization
mysql
mysql debin
xml
IBM XSL
w3c标准的xpath说明
web service ibm
XPath 示例
XPath 简单语法
XQuery 1.0 and XPath 2.0 Full-Text Use Cases
关注
Doug Lea's Home Page
压力测试
JMeter使用技巧
算法
排列组合算法
最新随笔
1. 解决Redis数据库响应延迟问题(转载)
2. 理想化的 Redis 集群 (转载)
3. Redis 分区(翻译)
4. Mysql索引相关知识分享
5. 数据结构-BinaryTree
6. 深入学习Linux之命令篇-find
7. 什么情况下应该使用GridFS(翻译)
8. Mongodb主从复制实践
9. jmap使用
10. 为什么实现了equal方法,一定需要实现hashCode方法呢?
11. MongoDB学习—MongoDB安装
12. 京东碰到的一道面试题
13. HashMap分析
14. 12个小球其中有一个是次品,不过不知道轻重,请问用天平能用三次测量的机会找出那个次品吗?
15. 使用java nio 实现 Ping
16. Spring 源码阅读(IOC容器)-容器启动2
17. Spring 源码阅读(IOC容器)-容器启动1
18. JDBC SavePoint浅析
19. Linux下C访问MySQL实践
20. Apache Benchmark(ab)使用
21. Java NIO Demo
22. Amoeba源码解读一
23. 编写跨平台代码注意事项
24. 编写跨平台代码注意事项
25. JavaScript的toString()方法自动调用
搜索
积分与排名
积分 - 95547
排名 - 602
最新评论
1. 嗯嗯
阿斯达斯
--安德森
2. re: tomcat 产生heapdump文件配置
如果不内存溢出,heapdump目录是不是空的?
--小龙在线
3. re: Java NIO Demo
评论内容较长,点击标题查看
--zuidaima
4. re: Redis 分区(翻译)
手机赚钱软件
http://www.szapk.cn
!!!
--手机赚钱软件http://www.szapk.cn
5. re: Mysql索引相关知识分享
很有价值的分享,值得学习
--任务大厅
阅读排行榜
1. Apache Benchmark(ab)使用(3212)
2. Linux下C访问MySQL实践(3121)
3. Java NIO Demo(2781)
4. 创建mysql innodb数据库(2629)
5. JDBC SavePoint浅析(2522)
评论排行榜
1. Mysql索引相关知识分享(4)
2. 京东碰到的一道面试题(1)
3. Linux下C访问MySQL实践(1)
4. Apache Benchmark(ab)使用(1)
5. Java NIO Demo(1)
6. JavaScript的toString()方法自动调用(1)
7. lucene 实践(1)
8. Redis 分区(翻译)(1)
9. 解决Redis数据库响应延迟问题(转载)(0)
10. 理想化的 Redis 集群 (转载)(0)
11. dom4j学习笔记(0)
12. 创建mysql innodb数据库(0)
13. Amoeba源码解读一(0)
14. 编写跨平台代码注意事项(0)
15. 编写跨平台代码注意事项(0)
16. HashMap分析(0)
17. 12个小球其中有一个是次品,不过不知道轻重,请问用天平能用三次测量的机会找出那个次品吗?(0)
18. 使用java nio 实现 Ping(0)
19. Spring 源码阅读(IOC容器)-容器启动2(0)
20. Spring 源码阅读(IOC容器)-容器启动1(0)