Apache MINA(Multipurpose Infrastructure for Network Applications) 是 Apache 組織一個較新的項目,它爲開發高性能和高可用性的網絡應用程序提供了非常便利的框架。當前發行的 MINA 版本支持基於 Java NIO 技術的 TCP/UDP 應用程序開發、串口通訊程序(只在最新的預覽版中提供),MINA 所支持的功能也在進一步的擴展中。目前正在使用 MINA 的軟件包括有:Apache Directory Project、AsyncWeb、AMQP(Advanced Message Queuing Protocol)、RED5 Server(Macromedia Flash Media RTMP)、ObjectRADIUS、Openfire 等等。
MINA的幾個重要接口:
IoServiece :這個接口在一個線程上負責套接字的建立,擁有自己的 Selector,監聽是否有連接被建立。
IoProcessor :這個接口在另一個線程上負責檢查是否有數據在通道上讀寫,也就是說它也擁有自己的 Selector,這是與我們使用 JAVA NIO 編碼時的一個不同之處,通常在JAVA NIO 編碼中,我們都是使用一個 Selector,也就是不區分 IoService與 IoProcessor 兩個功能接口。另外,IoProcessor 負責調用註冊在 IoService 上的過濾器,並在過濾器鏈之後調用
IoHandler。
IoAccepter :相當於網絡應用程序中的服務器端,它繼承自IoServiece,並進行了擴展。
IoConnector :相當於客戶端,它繼承自IoServiece,並進行了擴展。
IoSession :當前客戶端到服務器端的一個連接實例。
IoHandler :這個接口負責編寫業務邏輯,也就是接收、發送數據的地方。這也是實際開發過程中需要用戶自己編寫的部分代碼。
IoFilter :過濾器用於懸接通訊層接口與業務層接口,這個接口定義一組攔截器,這些攔截器可以包括日誌輸出、黑名單過濾、數據的編碼(write 方向)與解碼(read 方向)等功能,其中數據的 encode與 decode是最爲重要的、也是你在使用 Mina時最主要關注的地方。
MINA的基礎架構圖:
下面是使用Mina實現TCP的一個小例子:
TCPServer.java
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.LineDelimiter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
/**
* @description:Mina 實現TcpServer
* @date:(2015-11-22 下午3:46:23)
* @author
* @version v1.0
* @since v1.0
*
* Modified history
*
* Modified date: Modifier user: description:
*
* */
public class TcpServer{
public static void main(String[] args) throws IOException {
IoAcceptor acceptor=new NioSocketAcceptor();
//設置緩衝區大小
acceptor.getSessionConfig().setReadBufferSize(2048);
//設置通道10秒內沒有任何操作將處於空閒狀態
acceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 10);
//使用字符串編碼
acceptor.getFilterChain().addLast("codec",
new ProtocolCodecFilter(new TextLineCodecFactory(
Charset.forName("UTF-8"), LineDelimiter.WINDOWS.getValue()
,LineDelimiter.WINDOWS.getValue())));
//設置業務處理邏輯
acceptor.setHandler(new MyIOHandler());
acceptor.bind(new InetSocketAddress(9123));
}
}
MyIOHandler.java
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
/**
* @description:主要是一些業務邏輯,如發送,接收消息
* @date:(2015-11-24 上午9:37:02)
* @author Administrator
* @version v1.0
* @since v1.0
*
* Modified history
*
* Modified date:
* Modifier user:
* description:
*
* */
public class MyIOHandler extends IoHandlerAdapter{
/**
* 當有異常發生時觸發
* */
@Override
public void exceptionCaught(IoSession session, Throwable cause)
throws Exception {
super.exceptionCaught(session, cause);
session.close(true);
}
/**
* 有新連接是觸發
* */
@Override
public void sessionOpened(IoSession iosession) throws Exception {
System.out.println("session open for " + iosession.getRemoteAddress());
}
/**
* 連接被關閉是觸發
* */
@Override
public void sessionClosed(IoSession iosession) throws Exception {
System.out.println("session closed from " + iosession.getRemoteAddress());
}
/**
* 收到來自客戶端的消息
*/
@Override
public void messageReceived(IoSession iosession, Object message)
throws Exception {
String str=message.toString();
System.out.println("The message received is [" + str + "]");
if(str.endsWith("quit")){
iosession.close(true);
}
}
}
啓動服務,在dos窗口中telnet 127.0.0.1 9123
輸入:Helllo,MINA.
控制檯將輸出:
session open for /127.0.0.1:55344
The message received is [hello MINA]
Mina實現TCP客戶端:
MyCient.java
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.LineDelimiter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
/**
* @description:MINA 實現TCP 客戶端
* @date:(2015-11-24 下午10:06:43)
* @author Administrator
* @version v1.0
* @since v1.0
*
* Modified history
*
* Modified date:
* Modifier user:
* description:
*
* */
public class MyCient {
public static void main(String[] args) {
IoConnector connector=new NioSocketConnector();
connector.setConnectTimeoutMillis(30000);
connector.getFilterChain().addLast("codec",
new ProtocolCodecFilter(
new TextLineCodecFactory(Charset.forName("UTF-8"),
LineDelimiter.WINDOWS.getValue(),
LineDelimiter.WINDOWS.getValue())));
connector.setHandler(new ClientHandler("你好!\r\n 大家好!"));
connector.connect(new InetSocketAddress("127.0.0.1", 9123));
}
}
ClientHandler.java
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
/**
* @description
* @date:(2015-11-24 下午10:14:04)
* @author Administrator
* @version v1.0
* @since v1.0
*
* Modified history
*
* Modified date:
* Modifier user:
* description:
*
* */
public class ClientHandler extends IoHandlerAdapter{
private String values;
public ClientHandler(String values){
this.values=values;
}
@Override
public void sessionOpened(IoSession session) throws Exception {
session.write(values);
}
}
運行TCPServer,java,MyClient.java
server端控制檯輸出:
session open for /127.0.0.1:56992
The message received is [你好!]
The message received is [ 大家好!]
參考文檔:
http://www.ibm.com/developerworks/cn/opensource/os-cn-apmina/
http://www.cnblogs.com/xuekyo/archive/2013/03/06/2945826.html