目前项目里采用了淘宝的tair作为缓存,最近在研究tair的client端源码,发现通讯时用的是apache的mina框架。mina是一个基于NIO的异步通讯框架,下面写一个简单的关于NIO通信的例子。
服务端:
package com.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.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
public class NIOServer {
private Selector selector;
public void initServer(){
try {
//用于在channel上注册,这样一个channel可以管理多个事件
selector = Selector.open();
//生成channel
ServerSocketChannel ssc = ServerSocketChannel.open();
//设置成非阻塞
ssc.configureBlocking(false);
//获取socket,绑定需要服务端需要监听的端口。
ssc.socket().bind(new InetSocketAddress(8081));
//channel上注册selector,注册的事件类型为accept
ssc.register(selector, SelectionKey.OP_ACCEPT);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void serverListener(){
System.out.println("start server");
while(true){
try {
//开始监听
selector.select();
//获取channel上的监听事件组
Set<selectionkey> keys = selector.selectedKeys();
Iterator ite = keys.iterator();
while(ite.hasNext()){
SelectionKey key = (SelectionKey)ite.next();
ite.remove();
//监听的事件类型为accept时
if(key.isAcceptable()){
ServerSocketChannel ssc = (ServerSocketChannel)key.channel();
//接收,获取通讯用的socket
SocketChannel sc = ssc.accept();
sc.configureBlocking(false);
System.out.println("Connection has been accept");
//发一条信息
sc.write(ByteBuffer.wrap(new String("I'm sever,I want to talk").getBytes()));
//channel上注册selector,注册的事件类型为read
sc.register(selector, SelectionKey.OP_READ);
}else if(key.isReadable()){
read(key);
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void read(SelectionKey key){
ByteBuffer bb = ByteBuffer.allocate(1024);
SocketChannel sc = (SocketChannel)key.channel();
try {
sc.read(bb);
byte[] bytemsg = bb.array();
System.out.println("Server receive msg"+new String(bytemsg));
sc.write(ByteBuffer.wrap(new String("shou dao msg").getBytes()));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* @param args
*/
public static void main(String[] args) {
NIOServer server = new NIOServer();
server.initServer();
server.serverListener();
}
}
</selectionkey>
客户端:
<p>
package com.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;
public class NIOClient {
private Selector selector;
public void initClient(){
try {
selector = Selector.open();
SocketChannel channel = SocketChannel.open();
channel.configureBlocking(false);
//设置要访问的server的ip和port
channel.connect(new InetSocketAddress("localhost", 8081));
//channel上注册selector,注册的事件类型为connect
channel.register(selector, SelectionKey.OP_CONNECT);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void clientListener(){
while(true){
try {
selector.select();
Set<selectionkey> keys = selector.selectedKeys();
Iterator it = keys.iterator();
while(it.hasNext()){
SelectionKey key = (SelectionKey)it.next();
it.remove();
//当事件类型为connect时
if(key.isConnectable()){
SocketChannel sc = (SocketChannel)key.channel();
//判断connect操作是否在channel上进行
if(sc.isConnectionPending()){
//完成connect操作
sc.finishConnect();
}
sc.configureBlocking(false);
System.out.println("Connection has been established");
sc.write(ByteBuffer.wrap(new String("Hello world hehe").getBytes()));
sc.register(selector, SelectionKey.OP_READ);
}else if(key.isReadable()){
read(key);
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public void read(SelectionKey key){
SocketChannel sc = (SocketChannel)key.channel();
ByteBuffer bb = ByteBuffer.allocate(1024);
try {
sc.read(bb);
byte[] bytemsg = bb.array();
String msg = new String(bytemsg);
System.out.println("Client receive message"+msg);
ByteBuffer outBuffer = ByteBuffer.wrap(msg.getBytes());
sc.write(outBuffer);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args){
NIOClient client = new NIOClient();
client.initClient();
client.clientListener();
}
}
</selectionkey>