1) 服务端
package niotest.server;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
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.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.util.Iterator;
public class NioServer {
public static int BLOCK = 1024;
private Selector selector;
private ByteBuffer clientBuffer = ByteBuffer.allocate(BLOCK);
private CharsetDecoder decoder;
private static String name = "";
public static CharsetEncoder encoder = Charset.forName("GB2312").newEncoder();
public NioServer(int port) throws IOException {
selector = this.getSelector(port);
Charset charset = Charset.forName("GB2312");
decoder = charset.newDecoder();
System.out.println("NioServer starting...");
}
// 获得Selector,打开监听
private Selector getSelector(int port) throws IOException{
// 新建nio通道
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
// 建立选择器
Selector selector = Selector.open();
// 新建socket端口
serverSocketChannel.socket().bind(new InetSocketAddress(port));
// nio通道为非阻塞
serverSocketChannel.configureBlocking(false);
// 将nio通道绑定到选择器
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
return selector;
}
// 监听端口
public void listen() {
try{
//不断监听
while(true){
// 获取通道内是否有选择器关心的事件
int cnt = this.selector.select();
// 选择器关心的事件的集合
Iterator iter = selector.selectedKeys().iterator();
// 循环做处理
while (iter.hasNext()) {
// 遍历每个key
SelectionKey key = (SelectionKey) iter.next();
iter.remove();
doProcess(key);
}
}
}catch(Exception e){
e.printStackTrace();
}
}
// 处理事件
private void doProcess(SelectionKey key) throws IOException {
if(key.isAcceptable()) {
// 接收请求
ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();
// 得到请求
SocketChannel socketChannel = serverSocketChannel.accept();
// 非阻塞模式
socketChannel.configureBlocking(false);
// 注册
socketChannel.register(this.selector, SelectionKey.OP_READ);
} else if(key.isReadable()) {
// 读信息
SocketChannel socketChannel = (SocketChannel) key.channel();
int count = socketChannel.read(clientBuffer);
if(count > 0){
// 有内容的时候
clientBuffer.flip();
CharBuffer charBuffer = decoder.decode(clientBuffer);
name = charBuffer.toString();
SelectionKey selectionKey = socketChannel.register(selector, SelectionKey.OP_WRITE);
selectionKey.attach(name);
} else {
socketChannel.close();
}
clientBuffer.clear();
} else if(key.isWritable()){
// 写事件
SocketChannel socketChannel = (SocketChannel) key.channel();
String name = (String) key.attachment();
ByteBuffer block = encoder.encode(CharBuffer.wrap("Hello " + name));
socketChannel.write(block);
socketChannel.close(); // 该通道运行 结束
}
}
public static void main(String args[]) {
int port = 8888;
try{
NioServer nioServer = new NioServer(port);
// 启动 监听
nioServer.listen();
}catch(Exception e){
e.printStackTrace();
}
}
}
2) 客户端
package niotest.client;
import java.net.InetSocketAddress;
import niotest.NioMessage;
public class NioClient {
private static int SIZE = 10;
private static InetSocketAddress ip = new InetSocketAddress("localhost", 8888);
public static void main(String args[]) {
String name[] = new String[SIZE];
for(int i = 0; i < SIZE; i++) {
name[i] = "testMessage[" + i + "]" ;
new Thread(new NioMessage(name[i], ip)).start();
}
}
}
3)客户端 消息类
package niotest;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.util.Iterator;
public class NioMessage implements Runnable {
private String name = "";
private String message = "";
private InetSocketAddress ip;
private static CharsetEncoder encoder = Charset.forName("GB2312").newEncoder();
public NioMessage(String name, InetSocketAddress ip) {
this.name = name;
this.ip = ip;
}
@Override
public void run() {
try{
// TODO Auto-generated method stub
long start = System.currentTimeMillis();
// 打开socket通道
SocketChannel clientChannel = SocketChannel.open();
// 设为非阻塞
clientChannel.configureBlocking(false);
// 打开选择器
Selector selector = Selector.open();
// 注册连接服务端
clientChannel.register(selector, SelectionKey.OP_CONNECT);
// 连接
clientChannel.connect(ip);
// 缓冲区
ByteBuffer byteBuffer = ByteBuffer.allocate(10 * 1024);
int total = 0;
_FOR:while(true){
int cnt = selector.select();
Iterator iter = selector.selectedKeys().iterator();
while(iter.hasNext()) {
SelectionKey selectionKey = (SelectionKey) iter.next();
iter.remove();
if(selectionKey.isConnectable()){
// 连接
SocketChannel channel = (SocketChannel) selectionKey.channel();
if(channel.isConnectionPending()){
// 是否在当前进程中
channel.finishConnect();
channel.write(encoder.encode(CharBuffer.wrap(this.name)));
channel.register(selector, SelectionKey.OP_READ);
}
} else if(selectionKey.isReadable()){
// 读服务端返回来的信息
SocketChannel channel = (SocketChannel) selectionKey.channel();
int count = channel.read(byteBuffer);
if(count > 0) {
// 有内容的时候
total = total + count;
byteBuffer.flip();
while(byteBuffer.remaining() > 0) {
byte b = byteBuffer.get();
this.message = this.message + (char)b;
}
byteBuffer.clear();
} else {
clientChannel.close();
break _FOR;
}
}
}
}
double lastSecond = (System.currentTimeMillis() - start);
System.out.println(this.message + "used time :" + lastSecond + "ms.");
this.message = "";
} catch(Exception e){
e.printStackTrace();
}
}
}