JavaのNIOネットワークプログラミングのデモ

JavaのNIOを使用して、ネットワークプログラミングの例としては、サーバ側で見て

インポートにjava.io.IOException;
輸入java.net.InetAddress;
輸入java.net.InetSocketAddress。
インポートたjava.nio.ByteBuffer;
輸入java.nio.channels.SelectionKey。
輸入java.nio.channels.Selector。
輸入java.nio.channels.ServerSocketChannel。
輸入java.nio.channels.SocketChannel。
輸入はjava.util.ArrayList;
インポートするjava.util.Iterator;
輸入java.util.Randomの。
輸入java.util.Set;
輸入java.util.concurrent.ConcurrentHashMap; 

パブリック クラスサーバー{
     プライベート 静的 int型 PORT = 8000 ;
    プライベート 静的 最終 長い PAUSE_BETWEEEN_MSGS = 10; // millisecs 
    プライベート 静的のByteBuffer echoBuffer = ByteBuffer.allocate(4 )。
    プライベート 静的 ByteBufferのsendBuffer = ByteBuffer.allocate(256 );
    プライベート 静的のConcurrentHashMap <Integer型、のSocketChannel> CHM
             = 新しいのConcurrentHashMap <Integer型、のSocketChannel> ();
    プライベート 静的な int型 MSG = 0 ; 

公共の 静的な 無効メイン(文字列引数[])をスロー例外{ 
        セレクタセレクタ = Selector.openを();
        // 各ポートでリスナーを開き、各レジスタ 
        のServerSocketChannel SSC = )ServerSocketChannel.openを(。
        ssc.configureBlocking(); 
        たInetSocketAddressアドレス = たInetSocketAddress( "localhost"を、PORT); 
        ssc.bind(アドレス); 
        ssc.register(セレクタ、SelectionKey.OP_ACCEPT)。
        System.out.println( +「で待機するように行く」PORT)。
        一方、){
            selector.select(); 
            設定 <とSelectionKey> selectedKeys = selector.selectedKeys()。
            反復子 <とSelectionKey>は= selectedKeys.iterator()。

            System.out.println(selectedKeys.size())。
            一方、(it.hasNext()){ 
                文字列MSG = 新しい文字列()。
                SelectionKeyキー = (とSelectionKey)it.next();
                もし(key.isAcceptable()){ 
                    のServerSocketChannel sscNew = (のServerSocketChannel)キー
                            .channel()。
                    SocketChannel SC= sscNew.accept()。
                    sc.configureBlocking();
                    // セレクタへの新しい接続を追加
                    sc.register(セレクタ、SelectionKey.OP_READを)。
                    // リストにソケットチャネルを追加
                    chm.put(sc.hashCode()、サウスカロライナ州); 
                    it.remove(); 
                } そう であれば(key.isReadable()){ 
                    たSocketChannel SC = (のSocketChannel)key.channel();
                    int型コード= 0 一方、((コード= sc.read(echoBuffer))> 0){
                         バイト B [] = 新しい バイト[echoBuffer.position()]。
                        echoBuffer.flip(); 
                        echoBuffer.get(B)。
                        MSG + = 新しい文字列(B、 "UTF-8" ); 
                    } 
//                     IF(msg.length()> 1)
 //                         MSG = msg.substring(0、msg.length() - 2)。

                    // クライアント关闭时、收到可读事件、コード= -1 
                    であれば(コード== -1 || 
                            msg.toUpperCase()のindexOf( "BYE")> - 1 ){ 
                        chm.remove(sc.hashCode( )); 
                        sc.close()。
                    }{
                         // コード= 0、またはメッセージ読み取りechoBuffer十分なスペース、SELECT受信した後、メッセージの内容の次の部分
                        echoBuffer.clearを(); 
                    } 
                    のSystem.out.println( "MSG:" + SC + "コード:": "から" MSG + + + コード); 
                    it.remove(); 

                    // レジスタ書き込み通知
                    sc.register(セレクタ、SelectionKey.OP_WRITE); 
                } 他の IF (key.isWritable() ){ 
                    たSocketChannelクライアント = (のSocketChannel)key.channel(); 
                    文字列sendTxt= "メッセージサーバーから" 
                    it.remove()。
                    sendBuffer.put(sendTxt.getBytes()); 
                    sendBuffer.flip(); 
                    int型コード= 0 ; 

                    //をsendBufferコンテンツが一度終了していない場合は、次のイベントはそれに対処するのだろうか?
                    一方、(client.write(sendBuffer)!= 0 ){ 
                    } 
                    IF(コード== -1 ){ 
                        chm.remove(client.hashCode()); 
                        client.close(); 
                    } 他の{
                         // コード= 0、メッセージ終了
                        sendBuffer.clear(); 
                    } 
                    のSystem.out.println( "クライアントにメッセージを送ります" )。

                     // イベントとして登録されている読み書面による通知、そうも読み取るために、またはクライアント・メッセージ・受け入れないと登録することが必要とされて
                    client.register(セレクタ、SelectionKey.OP_READを); 
                } 
            } 
            のThread.sleep( 5000 ); 
        } 
    } 
}

ウィンドウのtelnetで、サーバーとの対話のTelnetウィンドウを使用して、次のように、行ごとにコマンドを送信したメッセージを送信する必要があります

いくつかの説明:

1.select操作イベントが発生し、少なくともまで、ブロッキング動作であります

最後2.serverのみ登録イベントを受け入れます

3.read、非ブロッキング書き込み動作は、コードで決定された結果を返す必要があります

あなたが同意する場合4.read操作、バッファサイズは、十分ではありませんあなたが選択する次回は、操作受付します

5.writeそれは動作しますか?メッセージが終了していない場合は、どのようにこのサイクルそれ以下に対処するには?

一方、(buffer.hasRemaining()){ 
                socketChannel.write(バッファ)
            }

6.registerは、書き込みレジスタで、そう交互に処理を上書きします

おすすめ

転載: www.cnblogs.com/darange/p/10954238.html