首页
Web开发
Windows程序
编程语言
数据库
移动开发
系统相关
微信
其他好文
会员
首页
>
编程语言
> 详细
java nio socket
时间:
2015-04-05 23:34:41
阅读:
327
评论:
0
收藏:
0
[点我收藏+]
标签:
java nio socket
jdk供的无阻塞I/O(NIO)有效解决了多线程服务器存在的线程开销问题,但在使用上略显得复杂一些。在NIO中使用多线程,主要目的已不是为了应对每个客户端请求而分配独立的服务线程,而是通过多线程充分使用用多个CPU的处理能力和处理中的等待时间,达到提高服务能力的目的。
这段时间在研究NIO,写篇博客来记住学过的东西。还是从最简单的Hello World开始,
client多线程请求server端,server接收client的名字,并返回Hello! +名字的字符格式给client。当然实际应用并不这么简单,实际可能是访问文件或者数据库获取信息返回给client。非阻塞的NIO有何神秘之处?代码:
1)server端代码
Java代码
/**
*
* @author Jeff
*
*/
public
class
HelloWorldServer {
static
int
BLOCK =
1024
;
static
String name =
""
;
protected
Selector selector;
protected
ByteBuffer clientBuffer = ByteBuffer.allocate(BLOCK);
protected
CharsetDecoder decoder;
static
CharsetEncoder encoder = Charset.forName(
"GB2312"
).newEncoder();
public
HelloWorldServer(
int
port)
throws
IOException {
selector =
this
.getSelector(port);
Charset charset = Charset.forName(
"GB2312"
);
decoder = charset.newDecoder();
}
// 获取Selector
protected
Selector getSelector(
int
port)
throws
IOException {
ServerSocketChannel server = ServerSocketChannel.open();
Selector sel = Selector.open();
server.socket().bind(
new
InetSocketAddress(port));
server.configureBlocking(
false
);
server.register(sel, SelectionKey.OP_ACCEPT);
return
sel;
}
// 监听端口
public
void
listen() {
try
{
for
(;;) {
selector.select();
Iterator iter = selector.selectedKeys().iterator();
while
(iter.hasNext()) {
SelectionKey key = (SelectionKey) iter.next();
iter.remove();
process(key);
}
}
}
catch
(IOException e) {
e.printStackTrace();
}
}
// 处理事件
protected
void
process(SelectionKey key)
throws
IOException {
if
(key.isAcceptable()) {
// 接收请求
ServerSocketChannel server = (ServerSocketChannel) key.channel();
SocketChannel channel = server.accept();
//设置非阻塞模式
channel.configureBlocking(
false
);
channel.register(selector, SelectionKey.OP_READ);
}
else
if
(key.isReadable()) {
// 读信息
SocketChannel channel = (SocketChannel) key.channel();
int
count = channel.read(clientBuffer);
if
(count >
0
) {
clientBuffer.flip();
CharBuffer charBuffer = decoder.decode(clientBuffer);
name = charBuffer.toString();
// System.out.println(name);
SelectionKey sKey = channel.register(selector,
SelectionKey.OP_WRITE);
sKey.attach(name);
}
else
{
channel.close();
}
clientBuffer.clear();
}
else
if
(key.isWritable()) {
// 写事件
SocketChannel channel = (SocketChannel) key.channel();
String name = (String) key.attachment();
ByteBuffer block = encoder.encode(CharBuffer
.wrap(
"Hello !"
+ name));
channel.write(block);
//channel.close();
}
}
public
static
void
main(String[] args) {
int
port =
8888
;
try
{
HelloWorldServer server =
new
HelloWorldServer(port);
System.out.println(
"listening on "
+ port);
server.listen();
}
catch
(IOException e) {
e.printStackTrace();
}
}
}
server主要是读取client发过来的信息,并返回一条信息
2)client端代码
Java代码
/**
*
* @author Jeff
*
*/
public
class
HelloWorldClient {
static
int
SIZE =
10
;
static
InetSocketAddress ip =
new
InetSocketAddress(
"localhost"
,
8888
);
static
CharsetEncoder encoder = Charset.forName(
"GB2312"
).newEncoder();
static
class
Message
implements
Runnable {
protected
String name;
String msg =
""
;
public
Message(String index) {
this
.name = index;
}
public
void
run() {
try
{
long
start = System.currentTimeMillis();
//打开Socket通道
SocketChannel client = SocketChannel.open();
//设置为非阻塞模式
client.configureBlocking(
false
);
//打开选择器
Selector selector = Selector.open();
//注册连接服务端socket动作
client.register(selector, SelectionKey.OP_CONNECT);
//连接
client.connect(ip);
//分配内存
ByteBuffer buffer = ByteBuffer.allocate(
8
*
1024
);
int
total =
0
;
_FOR:
for
(;;) {
selector.select();
Iterator iter = selector.selectedKeys().iterator();
while
(iter.hasNext()) {
SelectionKey key = (SelectionKey) iter.next();
iter.remove();
if
(key.isConnectable()) {
SocketChannel channel = (SocketChannel) key
.channel();
if
(channel.isConnectionPending())
channel.finishConnect();
channel
.write(encoder
.encode(CharBuffer.wrap(name)));
channel.register(selector, SelectionKey.OP_READ);
}
else
if
(key.isReadable()) {
SocketChannel channel = (SocketChannel) key
.channel();
int
count = channel.read(buffer);
if
(count >
0
) {
total += count;
buffer.flip();
while
(buffer.remaining() >
0
) {
byte
b = buffer.get();
msg += (
char
) b;
}
buffer.clear();
}
else
{
client.close();
break
_FOR;
}
}
}
}
double
last = (System.currentTimeMillis() - start) *
1.0
/
1000
;
System.out.println(msg +
"used time :"
+ last +
"s."
);
msg =
""
;
}
catch
(IOException e) {
e.printStackTrace();
}
}
}
public
static
void
main(String[] args)
throws
IOException {
String names[] =
new
String[SIZE];
for
(
int
index =
0
; index < SIZE; index++) {
names[index] =
"jeff["
+ index +
"]"
;
new
Thread(
new
Message(names[index])).start();
}
}
}
java nio socket
标签:
java nio socket
原文地址:http://blog.csdn.net/zhangping871/article/details/44892779
踩
(
0
)
赞
(
0
)
举报
评论
一句话评论(
0
)
登录后才能评论!
分享档案
更多>
2021年07月29日 (22)
2021年07月28日 (40)
2021年07月27日 (32)
2021年07月26日 (79)
2021年07月23日 (29)
2021年07月22日 (30)
2021年07月21日 (42)
2021年07月20日 (16)
2021年07月19日 (90)
2021年07月16日 (35)
周排行
更多
Spring Cloud 从入门到精通(一)Nacos 服务中心初探
2021-07-29
基础的排序算法
2021-07-29
SpringBoot|常用配置介绍
2021-07-29
关于 .NET 与 JAVA 在 JIT 编译上的一些差异
2021-07-29
C语言常用函数-toupper()将字符转换为大写英文字母函数
2021-07-29
《手把手教你》系列技巧篇(十)-java+ selenium自动化测试-元素定位大法之By class name(详细教程)
2021-07-28
4-1 YAML配置文件 注入 JavaBean中
2021-07-28
【python】 用来将对象持久化的 pickle 模块
2021-07-28
马拉车算法
2021-07-28
用Python进行冒泡排序
2021-07-28
友情链接
兰亭集智
国之画
百度统计
站长统计
阿里云
chrome插件
新版天听网
关于我们
-
联系我们
-
留言反馈
© 2014
mamicode.com
版权所有 联系我们:gaon5@hotmail.com
迷上了代码!