第 1 章では、MINA について一般的に理解しました。この章では、MINA のクライアント/サーバー モデルを詳細に分析します。 TCP と UDP に基づくいくつかの例も提供されます。
アプリケーション構造
サーバー構造
クライアント構造
シンプルな TCP サーバー
シンプルな TCP クライアント
シンプルな UDP サーバー
シンプルな UDP クライアント
アプリケーション構造の概要
MINA フレームワークを使用したもの アプリケーション構造は次のとおりです。
上の図からわかるように、MINA はアプリケーションとネットワークの最下層を接続する中間層として機能し、TCP、UDP、さらにはシリアル通信プロトコル (RS-232C) も処理できるため、次のことが可能です。基盤となるネットワーク通信の複雑さを理解せずに、MINA 上のアプリケーションの設計に重点を置くことになります。
MINA の内部を見てみましょう:一般的に、MINA アプリケーションは 3 つのレイヤーに分かれています。
I/O サービス - 実際の I/O 操作I/O フィルター チェーン - データのフィルター/送信
I/O ハンドラー - ここでプログラムのロジックを完成させます
したがって、MINA アプリケーションを作成するには、必要なのは Do :
I/O サービスの作成 - 提供されたサービス (アクセプター) を選択するか、独自のサービスを作成します
フィルター チェーンの作成 - 提供されたフィルター チェーンを選択するか、独自にカスタマイズしたフィルター チェーンを作成します
I/OHandler の作成 - ビジネス ロジックを作成し、さまざまな処理を行います上記は MINA の全体的な構造です
サーバー側の構造を見てみましょう:
簡単に言えば、今後の接続またはデータを監視するための I/O アクセプターがあります。新しい接続が到着すると、新しいセッションが作成され、この接続からの後続のリクエストはこのセッションで処理されます。すべてのパケットはセッションによって受け入れられ、上の図に示されているフィルタリング チェーンを通過します。フィルター チェーンは、パッケージの内容を変更する (オブジェクトへの変換、情報の追加または削除など) ために使用されます。最後に、これらのパケットは IOHandler によって処理されます。もう 1 つ注意すべき点は、接続が到着すると、接続が成功したかどうかに関係なく、セッションが確立されることです。
以下はクライアント モデルです: クライアントとサーバーはまったく逆の状態にあります。
シンプルな TCP サーバー
次に、デモとしてシンプルな TCP サーバーを作成します。まず、いくつかの必要なパッケージを IDE にインポートするか、CLASSPATH を構成する必要があります。必要なパッケージについては詳しく説明しません。 MINA 2.x Core
JDK 1.5以降
SLF4J 1.3.0以降
Log4J 1.2ユーザー: slf4j-api.jar、slf4j-log4j12.jar、およびLog4J 1.2.x
Log4J 1.3ユーザー: slf4j-api。 、slf4j-log4j13.jar、および Log4J 1.3.x
java.util.logging ユーザー: slf4j-api.jar および slf4j-jdk14.jar
重要: 以下に一致する正しい slf4j-*.jar を使用していることを確認してください。あなたのロギングフレームワークです。
準備作業が完了したら、コードを書き始めます
import java.net.InetSocketAddress; import org.apache.mina.core.service.IoAcceptor; import org.apache.mina.transport.socket.nio.NioSocketAcceptor; public class MinaTimeServer { private static final int PORT = 9123; public static void main( String[] args ) throws IOException { IoAcceptor acceptor = new NioSocketAcceptor(); acceptor.bind( new InetSocketAddress(PORT) ); } }
import java.io.IOException; import java.net.InetSocketAddress; import java.nio.charset.Charset; import org.apache.mina.core.service.IoAcceptor; import org.apache.mina.filter.codec.ProtocolCodecFilter; import org.apache.mina.filter.codec.textline.TextLineCodecFactory; import org.apache.mina.filter.logging.LoggingFilter; import org.apache.mina.transport.socket.nio.NioSocketAcceptor; public class MinaTimeServer { public static void main( String[] args ) { IoAcceptor acceptor = new NioSocketAcceptor(); acceptor.getFilterChain().addLast( "logger", new LoggingFilter() ); //这里会建立所有的日志信息 acceptor.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" )))); //第二个过滤器用来传递数据 acceptor.bind( new InetSocketAddress(PORT) ); } }
import java.util.Date; import org.apache.mina.core.session.IdleStatus; import org.apache.mina.core.service.IoHandlerAdapter; import org.apache.mina.core.session.IoSession; public class 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 )); } }最後に、完全なサーバー コードは次のとおりです:
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.TextLineCodecFactory; import org.apache.mina.filter.logging.LoggingFilter; import org.apache.mina.transport.socket.nio.NioSocketAcceptor; public class MinaTimeServer { private static final int PORT = 9123; public static void main( String[] args ) throws IOException { IoAcceptor acceptor = new NioSocketAcceptor(); acceptor.getFilterChain().addLast( "logger", new LoggingFilter() ); acceptor.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" )))); acceptor.setHandler( new TimeServerHandler() ); //这里设置Handler acceptor.getSessionConfig().setReadBufferSize( 2048 ); //这是设置ssesion缓冲区 acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 ); acceptor.bind( new InetSocketAddress(PORT) ); } }サーバーを実行し、ターミナルを開いてコマンド telnet 127.0.0.1 9123 を入力します。「quit」以外の文字を入力すると、サーバーは現在の値を返します。ターミナルに来る時間です。 単純な TCP クライアント
import java.net.InetSocketAddress; import org.apache.mina.core.RuntimeIoException; import org.apache.mina.core.future.ConnectFuture; import org.apache.mina.core.session.IoSession; import org.apache.mina.example.sumup.codec.SumUpProtocolCodecFactory; import org.apache.mina.filter.codec.ProtocolCodecFilter; import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory; import org.apache.mina.filter.logging.LoggingFilter; import org.apache.mina.transport.socket.nio.NioSocketConnector; /** * (<strong>Entry Point</strong>) Starts SumUp client. * * @author <a href="http://mina.apache.org">Apache MINA Project</a> */ public class Client { private static final String HOSTNAME = "localhost"; private static final int PORT = 8080; private static final long CONNECT_TIMEOUT = 30*1000L; // 30 seconds // Set this to false to use object serialization instead of custom codec. private static final boolean USE_CUSTOM_CODEC = true; public static void main(String[] args) throws Throwable { if (args.length == 0) { System.out.println("Please specify the list of any integers"); return; } // prepare values to sum up int[] values = new int[args.length]; for (int i = 0; i < args.length; i++) { values[i] = Integer.parseInt(args[i]); } NioSocketConnector connector = new NioSocketConnector(); // Configure the service. connector.setConnectTimeoutMillis(CONNECT_TIMEOUT); if (USE_CUSTOM_CODEC) {
connector.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new SumUpProtocolCodecFactory(false))); } else { connector.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new ObjectSerializationCodecFactory())); } connector.getFilterChain().addLast("logger", new LoggingFilter()); connector.setHandler(new ClientSessionHandler(values)); IoSession session; for (;;) { try { ConnectFuture future = connector.connect(new InetSocketAddress( HOSTNAME, PORT)); future.awaitUninterruptibly(); session = future.getSession(); break; } catch (RuntimeIoException e) { System.err.println("Failed to connect."); e.printStackTrace(); Thread.sleep(5000); } } // wait until the summation is done session.getCloseFuture().awaitUninterruptibly(); connector.dispose(); } }UDP の例はここには書かれていません。必要に応じて、Apache 公式 Web サイトにアクセスしてご覧ください。
http://mina.apache.org/mina-project/userguide/ch2-basics/sample-udp-client.html