1、學習資料html
Mina入門實例(一)
http://www.cnblogs.com/juepei/p/3939119.htmlapache
Mina入門教程(二)----Spring4 集成Mina
http://www.cnblogs.com/juepei/p/3940396.html緩存
Apache Mina 入門實例——建立一個MINA時間服務
http://loftor.com/archives/apache-mina-quick-start-guide.htmlsession
MINA2.0用戶手冊中文版——系列文檔
http://blog.csdn.net/lxlzhn/article/category/1272213/2框架
mina 心跳機制
出處:http://wandejun1012.iteye.com/blog/2065941ide
mina框架詳解
http://www.cnblogs.com/gw811/p/4279230.html學習
Mina系列文章索引(解碼解析等,不錯)
http://my.oschina.net/ielts0909/blog/92716編碼
2、代碼示例
(1)Mina服務端建立步驟
1.創建監聽對象
IoAcceptor acceptor=new NioSocketAcceptor();
2.添加Filter(日誌,編解碼)
acceptor.getFilterChain().addLast("logger",new LoggingFilter());
acceptor.getFilterChain().addLast("codec",new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));url
3.添加Handler處理
acceptor.setHandler(new TimeServerHandler());
4.設置回話參數【輸入緩存區Buffer大小,多久進入空閒時間】
acceptor.getSessionConfig.setReadBufferSize(2048);
acceptor.getessionConfig.setIdleTime(IdleStatus.BOTH_IDLE,10);
5.綁定端口號,開始監聽
acceptor.bind(new InetSocketAddress(PORT));
Handler處理類開發
繼承IOHandler類或者實現IoHandler接口
客戶端Handler,服務端Handler使用同一個IOHandler繼承實現。
public TimeServerHandler extends IoHandlerAdapter
{
@Override
public void exceptionCaught(IoSession session,Throwable cause) throws Exception
{
cause.printStackTrace();
}
@Override
public void messageReceived(IoSession session,Object message) throws Exception
{
String str=message.toString();
if(str.trim().equalsIgnoreCase("quit"))
{
session.close();
return ;
}
Date date=new Date();
session.write(date.toString());
System.out.println("Message written...");
}
@Override
public void sessionIdle(IoSession session,IdleStatus status) throws Exception
{
System.out.println("IDLE"+session.getIdleCount(status));
}
}
exceptionCaught方法:捕獲錯誤,簡單地打印了錯誤的堆棧跟蹤和關閉會話。
messageReceived方法:來處理從客戶端接收到的數據,這裏是將當前時間返回給客戶端。根據所使用的協議編解碼器,object 這個參數傳遞的類型有所不一樣,以及返回的數據時的session.write(Object) 也不一樣。若是不指定協議的編解碼器,你將收到一個類型爲IoBuffer 的對象,返回的數據也要求是IoBuffer。
sessionIdle方法:空閒狀態時,將定時調用一次會話
還有如下幾個方法重寫
@Override
public void messageSent(IoSession arg0, Object message) throws Exception {
// TODO Auto-generated method stub
System.out.println("client發送信息"+message.toString());
}
@Override
public void sessionClosed(IoSession session) throws Exception {
// TODO Auto-generated method stub
System.out.println("client與:"+session.getRemoteAddress().toString()+"斷開鏈接");
}
@Override
public void sessionCreated(IoSession session) throws Exception {
// TODO Auto-generated method stub
System.out.println("client與:"+session.getRemoteAddress().toString()+"創建鏈接");
}
@Override
public void sessionOpened(IoSession arg0) throws Exception {
// TODO Auto-generated method stub
System.out.println("打開鏈接");
}
(2)Mina客戶端建立
1.建立客戶端鏈接對象
IoConnector connector=new NioSocketConnector();或者NioSocketConnector connector = new NioSocketConnector();
2.設置過濾器職責鏈(日誌,編解碼【多種編解碼器】)
connector.getFilterChain().addLast("logger",new LoggingFilter());
connector.getFilterChain().addLast("codec",new ProtocolCodecFilter(new PrefixedStringCodecFactory(Charset.forName("UTF-8"))));
也能夠使用
ioAcceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8"))));
3.設置Handler處理
connector.setHandler(new TimeClientHandler());
4.創建Connect鏈接
ConnectFuture connectFuture=connector.connect(new InetSocketAddress("127.0.0.1",BaseConfig.PORT));
connectFuture.awaitUninterruptibly();
5.得到Session回話
IoSession session=connectFuture.getSession();
6.輸入輸出操做
如下是接收控制檯的輸入,得到後發送到服務端
Scanner sc = new Scanner(System.in);
boolean quit = false;
while(!quit){
String str = sc.next();
if(str.equalsIgnoreCase("quit")){
quit = true;
}
session.write(str);
}
7.關閉Session和鏈接器
if(session!=null){
if(session.isConnected()){
session.getCloseFuture().awaitUninterruptibly();
}
connector.dispose(true);
}
IoConnector connector = new NioSocketConnector();
connector.getFilterChain().addLast( "logger", new LoggingFilter() );
connector.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new PrefixedStringCodecFactory(Charset.forName("UTF-8"))));
connector.setHandler(new TimeClientHander());
ConnectFuture connectFuture = connector.connect(new InetSocketAddress("127.0.0.1",BaseConfig.PORT));
//等待創建鏈接
connectFuture.awaitUninterruptibly();
System.out.println("鏈接成功");
IoSession session = connectFuture.getSession();
Scanner sc = new Scanner(System.in);
boolean quit = false;
while(!quit){
String str = sc.next();
if(str.equalsIgnoreCase("quit")){
quit = true;
}
session.write(str);
}
//關閉
if(session!=null){
if(session.isConnected()){
session.getCloseFuture().awaitUninterruptibly();
}
connector.dispose(true);
}
3、粘包分包處理
有三種經常使用方法能夠將字節流分離成消息:
使用固定長度的消息。
使用固定長度的標頭指出消息內容主體的長度。
使用分隔符;例如不少基於文本的消息在消息的後面追加換行(或者CR LF組合) (http://www.faqs.org/rfcs/rfc977.html)