1.サーバー
インポートにjava.io.IOException; 輸入java.net.InetSocketAddress; インポートたjava.nio.ByteBuffer; 輸入いるjava.nio.channels *。; インポートするjava.util.Iterator; 輸入java.util.Set; パブリック クラスGroupChatServer { 民間セレクターセレクター。 民間のServerSocketChannel listenChannel。 プライベート 静的 最終 int型の PORT = 8888 ; // 构造器 パブリックGroupChatServer(){ 試み{ セレクタ = Selector.open()。 listenChannel = ServerSocketChannel.open(); // バインドポート listenChannel.socket()バインド(新新たInetSocketAddress(PORT)); // モードノンブロッキングセット (listenChannel.configureBlocking falseにする); // listenChannelはセレクタ登録 listenChannelを。登録(セレクタ、SelectionKey.OP_ACCEPT); } キャッチ(例外E){ e.printStackTrace(); } } / ** *リスニング * / 公共の 無効(聞く){ 試み{ 一方(真の){ // SELECT(2000)だけ2秒遮断 // INT COUNT = selector.select(2000); // SELECT()メソッドブロック INT COUNT = selector.select(); IF(COUNT> 0 ){ // 反復とSelectionKeyが設定されたすべて取得する イテレータ <とSelectionKey> keysIterator = selector.selectedKeys()イテレータ();. 一方(keysIterator.hasNext()){ // プロセスそれぞれとSelectionKey とSelectionKeyとSelectionKey =をkeysIterator.next(); // 監視接続イベント IF (selectionKey.isAcceptable()){ たSocketChannelのSocketChannel = listenChannel.accept(); socketChannel.configureBlocking(偽の); // レジスタ socketChannel.register(セレクタ、SelectionKey.OP_READ) ; // ラインプロンプト するSystem.out.println( "オンライン" socketChannel.getRemoteAddress()+ ); } // チャネル可読イベント なら(selectionKey.isReadable()){ // リード処理TODO ReadMessage(とSelectionKey); } // 重複処理防止するために、Deleteキーを keysIterator.removeを(); } } 他{ // するSystem.out.println(「待機.. ..「); } } } キャッチ(例外E){ e.printStackTrace(); } } / ** *読み込み、クライアントのメッセージ * * @param キー * / 公共 のボイドReadMessage(とSelectionKeyキー){ のSocketChannelたSocketChannel = ヌル; 試み{ のSocketChannel = (たSocketChannel)key.channel(); のByteBufferのByteBuffer = ByteBuffer.allocate(1024 ); int型の読み取り= socketChannel.read(ByteBufferの); // 読み取り読み取り> 0が本当にデータを読み込む説明している場合我々は、値を扱う IF(読み取り> 0 ){ 文字列メッセージ = 新しい新しい文字列(byteBuffer.array()); System.out.printlnは( "Form1のクライアント:" +メッセージ); // 他のクライアントへのTODOメッセージを転送 sendInfoToOtherClient(メッセージ、のSocketChannel); } } キャッチ(IOExceptionをE){ 試み{ System.out.printlnは(socketChannel.getRemoteAddress() + "はオフラインです..." ); // 登録オフライン後のキャンセル key.cancel(); // 閉じるチャネル socketChannel.close(); } キャッチ(IOExceptionをE1){ e1.printStackTrace(); } } } / ** *他のクライアントに転送したメッセージは、 * * @paramのメッセージ転送メッセージ * @paramの自己:除外チャンネル * / パブリック 無効 sendInfoToOtherClient(文字列メッセージ、のSocketChannelセルフ)がスローにIOException { System.out.printlnは(「サーバーに転送メッセージを。 .. " ); // すべての登録されたSocketChannel介して反復セレクタ、および排除する 設定<とSelectionKey>キー= Selector.keysを() のための(とSelectionKeyキー:キー){ // のSocketChannelキー対応で撮影された チャネルをtargetChannel = key.channel(); //は、自分自身を除外します もし(targetChannel のinstanceofのSocketChannel && targetChannel =!自己){ たSocketChannel目標 = (のSocketChannel)targetChannel。 // 将メッセージ存储到バッファ のByteBufferバッファ= ByteBuffer.wrap(message.getBytes())。 // 将バッファ中的数据写入通道 target.write(バッファ)。 } } } パブリック 静的 ボイドメイン(文字列[]引数){ // 创建对象 GroupChatServer chatServer = 新しいGroupChatServer()。 chatServer.listen(); } }
2.クライアント
インポートにjava.io.IOException; 輸入java.net.InetSocketAddress; インポートたjava.nio.ByteBuffer; 輸入java.nio.channels.SelectionKey。 輸入java.nio.channels.Selector; 輸入java.nio.channels.SocketChannel; インポートするjava.util.Iterator; インポートjava.util.Scanner; 輸入java.util.Set; パブリック クラスGroupChatClient { // 服务器IP 民間 最終文字列HOST = "127.0.0.1" 。 // 服务器端口 民間 最終 int型の PORT = 8888 ; 民間セレクターセレクター。 プライベートたSocketChannelたSocketChannel。 プライベート文字列のユーザ名。 パブリックGroupChatClient(){ 試み{ セレクタ = Selector.open()。 たSocketChannel = SocketChannel.open(新たInetSocketAddress(HOST、PORT)); socketChannel.configureBlocking(偽); socketChannel.register(セレクタ、SelectionKey.OP_READ)。 ユーザ名 = socketChannel.getLocalAddress()のtoString()サブストリング(1。 )。 System.out.println(ユーザ名 + "OK!"); } キャッチ(例外E){ e.printStackTrace(); } } / ** *サーバーにメッセージを送信する * * @paramの情報メッセージの内容 * / パブリック 無効sendInfo(文字情報){ 情報 =ユーザ名+「言います: 「+ 情報; 試し{ socketChannel.write(ByteBuffer.wrap(info.getBytes())); } キャッチ(IOExceptionをE){ e.printStackTrace(); } } / ** *は、サーバーからのメッセージ読み込み * / 公共の 空隙readInfo(){ 試み{ int型 readChannels = selector.select(2000 ); もし(readChannels> 0 ){ セット <とSelectionKey>キー= selector.selectedKeys()。 反復子 <とSelectionKey> keyInterator = keys.iterator()。 一方、(keyInterator.hasNext()){ とSelectionKeyとSelectionKey = keyInterator.next()。 もし(selectionKey.isReadable()){ // 得到读相关通道 のSocketChannelのSocketChannel =(たSocketChannel)selectionKey.channel(); のByteBufferのByteBuffer = ByteBuffer.allocate(1024 ); socketChannel.read(のByteBuffer); // 文字列に転送されるバッファデータ 文字列messge = 新しい新しい文字列(byteBuffer.array())。 System.out.println(messge.trim()); } // 現在とSelectionKey削除 keyInterator.removeを(); } } 他{ // するSystem.out.printlnを( "利用できないチャネル....") } } キャッチ(IOExceptionをE){ e.printStackTrace(); } } 公共の 静的な 無効メイン(文字列[] args)を{ // スタートクライアント GroupChatClient ChatClient = 新新GroupChatClient(); // 読み取りサービスから2秒ごとにスレッドを開始介してデータを送信し 、新たな新)(スレッド{ @Override 公共 無効RUN(){ ながら、(真の){ chatClient.readInfo(); 試み{ にThread.currentThread()SLEEP( 2000 ); } キャッチ(InterruptedExceptionあるE){ e.printStackTrace(); } } } } .start(); // 送信データがサーバに スキャナスキャナ= 新しい新しいスキャナ(System.in); 一方(Scanner.hasNext()){ 文字列情報 = Scanner.next(); chatClient.sendInfo(情報); } } }