nio之Selectordemo
来源:互联网 发布:守望先锋左上角数据vrm 编辑:程序博客网 时间:2024/06/07 14:03
package test;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.*;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.Iterator;
import java.util.Set;
/**
* Created by pc on 2014/12/30.
* http://ifeve.com/buffers/#clearandcompact
*/
public class Server {
static int PORT = 8080;
static int BUFFER_SIZE = 1024;
static String CHARSET = "utf-8"; //默认编码
CharsetDecoder decoder; //解码
private final int port;
private ServerSocketChannel channel;
private Selector selector;
private final ByteBuffer buffer;
public Server(int port) throws IOException {
this.port = port;
this.buffer = ByteBuffer.allocate(BUFFER_SIZE);
this.decoder = Charset.forName(CHARSET).newDecoder();
this.selector = Selector.open();//打开选择器
}
/**
* 单线程服务,通过单一个线程同时为多路复用IO流服务
* 1、此方式适合:IO密集型的操作:如代理服务.
* 2、相信大家写过:使用socket的聊天程序:
* 即accept()一个socket后,new一个Thread为该socket服务,
* 此方式适合:CPU密集型的操作,如需要处理大量业务、计算
*
* @throws IOException
*/
public void listen() throws IOException {
//打开一个服务通道
this.channel = ServerSocketChannel.open();
//绑定服务端口
ServerSocket socket = channel.socket();
socket.bind(new InetSocketAddress(port));
//使用非阻塞模式,使用多道io操作
channel.configureBlocking(false);
System.out.println("服务运行中...");
while (true) {
//非阻塞,没有连接,立即返回null,与socket.accept()方法(阻塞)不同,
SocketChannel client = channel.accept();
if (client != null) {
System.out.println("客户端口-->" + client.getRemoteAddress());
registerClient(client);
}
service();
}
}
/**
* 将客户端channel注册到selector上
* 四个事件:Connect、Accept、Read、Write
*
* @param client
* @throws IOException
*/
private void registerClient(SocketChannel client) throws IOException {
//设置非阻塞
client.configureBlocking(false);
//将客户端channel注册到selector上
client.register(selector, SelectionKey.OP_READ);
}
/**
* 遍历各客户端通道
* select()阻塞到至少有一个通道在你注册的事件上就绪了
* select(long timeout) 多设置一个阻塞时间(毫秒)
* selectNow() 不阻塞,有无都返回。
*/
private void service() throws IOException {
if (selector.selectNow() > 0) {
//客户端channel的键集合
Set<SelectionKey> keys = selector.selectedKeys();
System.out.println("selector长度-->" + keys.size());
Iterator<SelectionKey> it = keys.iterator();
while (it.hasNext()) {
SelectionKey key = it.next();
SocketChannel client = (SocketChannel) key.channel();
if (key.isReadable()) {
read(key);
} else if (key.isWritable()) {
write(key);
}
}
}
}
//读信息
private void read(SelectionKey key) throws IOException {
SocketChannel client = (SocketChannel) key.channel();
buffer.clear();
int c = client.read(buffer);
if (c > 0) {
//flip方法将Buffer从写模式切换到读模式
buffer.flip();
CharBuffer charBuffer = decoder.decode(buffer);
//接收请求
System.out.println(charBuffer.toString());
key.attach("ack syn...");
// 改变自身关注事件,可以用位或操作|组合时间
key.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
} else {
client.close();
}
buffer.clear();
}
//响应信息
private void write(SelectionKey key) throws IOException {
SocketChannel client = (SocketChannel) key.channel();
String handle = (String) key.attachment();//取出read方法传递的信息。
String res = Response.getMsg();
if (handle != null) {
res = res + "\r\n" + handle;
}
ByteBuffer block = ByteBuffer.wrap(res.getBytes());
client.write(block);
client.close();
// 改变自身关注事件,可以用位或操作|组合时间
//key.interestOps(SelectionKey.OP_READ);
}
public static void main(String[] args) {
try {
System.out.println("正在启动服务...");
Server server = new Server(PORT);
server.listen();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class Response {
public static String getMsg() {
return "HTTP/1.1 200 OK" + "\r\n";
}
}
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.*;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.Iterator;
import java.util.Set;
/**
* Created by pc on 2014/12/30.
* http://ifeve.com/buffers/#clearandcompact
*/
public class Server {
static int PORT = 8080;
static int BUFFER_SIZE = 1024;
static String CHARSET = "utf-8"; //默认编码
CharsetDecoder decoder; //解码
private final int port;
private ServerSocketChannel channel;
private Selector selector;
private final ByteBuffer buffer;
public Server(int port) throws IOException {
this.port = port;
this.buffer = ByteBuffer.allocate(BUFFER_SIZE);
this.decoder = Charset.forName(CHARSET).newDecoder();
this.selector = Selector.open();//打开选择器
}
/**
* 单线程服务,通过单一个线程同时为多路复用IO流服务
* 1、此方式适合:IO密集型的操作:如代理服务.
* 2、相信大家写过:使用socket的聊天程序:
* 即accept()一个socket后,new一个Thread为该socket服务,
* 此方式适合:CPU密集型的操作,如需要处理大量业务、计算
*
* @throws IOException
*/
public void listen() throws IOException {
//打开一个服务通道
this.channel = ServerSocketChannel.open();
//绑定服务端口
ServerSocket socket = channel.socket();
socket.bind(new InetSocketAddress(port));
//使用非阻塞模式,使用多道io操作
channel.configureBlocking(false);
System.out.println("服务运行中...");
while (true) {
//非阻塞,没有连接,立即返回null,与socket.accept()方法(阻塞)不同,
SocketChannel client = channel.accept();
if (client != null) {
System.out.println("客户端口-->" + client.getRemoteAddress());
registerClient(client);
}
service();
}
}
/**
* 将客户端channel注册到selector上
* 四个事件:Connect、Accept、Read、Write
*
* @param client
* @throws IOException
*/
private void registerClient(SocketChannel client) throws IOException {
//设置非阻塞
client.configureBlocking(false);
//将客户端channel注册到selector上
client.register(selector, SelectionKey.OP_READ);
}
/**
* 遍历各客户端通道
* select()阻塞到至少有一个通道在你注册的事件上就绪了
* select(long timeout) 多设置一个阻塞时间(毫秒)
* selectNow() 不阻塞,有无都返回。
*/
private void service() throws IOException {
if (selector.selectNow() > 0) {
//客户端channel的键集合
Set<SelectionKey> keys = selector.selectedKeys();
System.out.println("selector长度-->" + keys.size());
Iterator<SelectionKey> it = keys.iterator();
while (it.hasNext()) {
SelectionKey key = it.next();
SocketChannel client = (SocketChannel) key.channel();
if (key.isReadable()) {
read(key);
} else if (key.isWritable()) {
write(key);
}
}
}
}
//读信息
private void read(SelectionKey key) throws IOException {
SocketChannel client = (SocketChannel) key.channel();
buffer.clear();
int c = client.read(buffer);
if (c > 0) {
//flip方法将Buffer从写模式切换到读模式
buffer.flip();
CharBuffer charBuffer = decoder.decode(buffer);
//接收请求
System.out.println(charBuffer.toString());
key.attach("ack syn...");
// 改变自身关注事件,可以用位或操作|组合时间
key.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
} else {
client.close();
}
buffer.clear();
}
//响应信息
private void write(SelectionKey key) throws IOException {
SocketChannel client = (SocketChannel) key.channel();
String handle = (String) key.attachment();//取出read方法传递的信息。
String res = Response.getMsg();
if (handle != null) {
res = res + "\r\n" + handle;
}
ByteBuffer block = ByteBuffer.wrap(res.getBytes());
client.write(block);
client.close();
// 改变自身关注事件,可以用位或操作|组合时间
//key.interestOps(SelectionKey.OP_READ);
}
public static void main(String[] args) {
try {
System.out.println("正在启动服务...");
Server server = new Server(PORT);
server.listen();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class Response {
public static String getMsg() {
return "HTTP/1.1 200 OK" + "\r\n";
}
}
0 0
- nio之Selectordemo
- Java NIO 之 NIO 简介
- 【Java.NIO】NIO就绪处理之OP_CONNECT
- 【Java.NIO】NIO就绪处理之OP_ACCEPT
- 【Java.NIO】NIO就绪处理之OP_WRITE
- java nio学习之 socket+nio 通信
- Java NIO 之 NIO与IO比较
- java nio之Buffer
- java nio 之MappedByteBuffer
- java nio 之MappedByteBuffer
- nio之Buffer系列
- Java之nio学习
- java nio 之MappedByteBuffer
- JAVA NIO之FileChannel
- JAVA NIO之MappedByteBuffer
- JAVA NIO之selector
- nio之Buffer
- Java NIO 之 buffer
- dfs入门(2)
- 正则表达式符号字符大全
- 查找字符串中字母出现最多次数的方法小结
- ng2学习笔记(一)初识ng2
- 水果竞猜开奖游戏还可以这样玩
- nio之Selectordemo
- NSCache的简单使用介绍
- centos6.5的php5.3.3这个版本怎么升级到5.6
- ubuntu中安装Mysql
- nio Selector 阻塞 唤醒 原理
- wsimport的使用
- Spring框架(一)环境搭建、配置(xml、注解)、整合JDBC以及项目详解
- Sort Colors -- LeetCode
- 十进制转八进制