多くのチャットクライアントシステムをプログラミングNIO

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(情報); 
        } 

    } 
}

 

 

 

  

おすすめ

転載: www.cnblogs.com/z-qinfeng/p/11964363.html