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は、書き込みレジスタで、そう交互に処理を上書きします