package j5; // MCChat.java // マルチキャストを使ってチャット機能を提供 // 使い方 > java j5.MCChat import java.net.*; import java.io.*; import java.util.Arrays; //============================================================================== public class MCChat { // 受信スレッドを作成・実行し,送信を担当 final byte TTL = 1; //同一セグメント内部のみ到達可能とする final String MULTICASTADDRESS = ("224.0.0.1") ; // マルチキャストアドレス224.0.0.1はルータを超えない場合のアドレス int port = 7000; // マルチキャストチャット用のポート番号,指定がなければ7000 番とします byte[] buff = new byte[1024]; //送信用バッファ String myname ="" ; // 利用者名 int nameLength = 0; //利用者名の長さ MulticastSocket soc = null; // マルチキャストソケット InetAddress chatgroup = null; //チャット用アドレス // コンストラクタ利用者名などを設定します public MCChat(int portno){ port = portno ; //ポート番号の設定 BufferedReader lineread = new BufferedReader(new InputStreamReader(System.in)) ; System.out.print("Input your name: ") ; try{ myname = lineread.readLine() ; } catch(Exception e){ e.printStackTrace() ; System.exit(1) ; } System.out.println("Welcome " + myname + "!") ; myname = myname + ">" ; nameLength = (myname.getBytes()).length ; for(int i = 0;i < nameLength;++i) buff[i] = (myname.getBytes())[i] ; } //----------------------------------------------------------------------------- public void makeMulticastSocket() { // MULTICASTADDRESSに対してマルチキャストソケットを作成. try{ chatgroup = InetAddress.getByName(MULTICASTADDRESS) ; soc = new MulticastSocket(port) ; soc.joinGroup(chatgroup) ; } catch(Exception e){ e.printStackTrace() ; System.exit(1); } } // end of makeMulticastSocket //----------------------------------------------------------------------------- public void startListener() { // スレッド用クラスListenPacketのオブジェクトを生成し,起動. try{ ListenPacket lisner = new ListenPacket(soc); Thread lisner_thread = new Thread(lisner); lisner_thread.start();//受信スレッドの開始 } catch(Exception e){ e.printStackTrace() ; System.exit(1); } } // end of startListener //----------------------------------------------------------------------------- public void sendMsgs() { // マルチキャストパケットの送信を担当. try{ // 送信ループ while(true){ int n = System.in.read(buff, nameLength, 1024 - nameLength ) ; // if (n > 1){ //文字数が少ないときはコピー失敗するのでチェックしない // byte[] mesonly = Arrays.copyOfRange(buff, nameLength, nameLength+n-1); //debug for(byte b: mesonly){ //debug System.out.println(b); //debug } // String messtr = new String(mesonly); // byte array to string // if (messtr.equals("exit")) break; // } if(n > 0){ DatagramPacket dp = new DatagramPacket(buff, n + nameLength, chatgroup, port) ; soc.send(dp) ; } else break ;// CTRL+Dは n==0 になるので、ループ終了 // (Enterのみだと改行文字が含まれるため0に // ならない } } catch(Exception e){ e.printStackTrace() ; System.exit(1); } } // end of sendMsgs //----------------------------------------------------------------------------- public void quitGroup() { // 接続を終了 try{ System.out.println("Connection Closed.") ; soc.leaveGroup(chatgroup) ; System.exit(0) ; } catch(Exception e){ e.printStackTrace() ; System.exit(1); } } //----------------------------------------------------------------------------- public static void main(String[] arg){ MCChat c = null ; int portno = 7000 ; // コマンドライン引数があれば、使用ポート番号を設定する if (arg.length >= 1) portno = Integer.parseInt(arg[0]) ; c = new MCChat(portno) ; c.makeMulticastSocket() ; c.startListener() ; c.sendMsgs() ; c.quitGroup() ; } } // end of class MCChat //============================================================================== // ListenPacketクラス // マルチキャストパケットを受信します class ListenPacket implements Runnable { MulticastSocket s = null; // コンストラクタ: マルチキャストスレッドを受け取ります public ListenPacket(MulticastSocket soc){ s = soc; } // 処理の本体 public void run(){ byte[] buff = new byte[1024] ; try{ while(true){ DatagramPacket recv = new DatagramPacket(buff,buff.length) ; s.receive(recv) ; if(recv.getLength() > 0){ System.out.write(buff,0,recv.getLength()) ; } } } catch(Exception e){ e.printStackTrace() ; System.exit(1) ; } } } // end of class ListenPacket