Newer
Older
myNWP2 / src / j5 / MCChat.java
@Motoki Miura Motoki Miura on 22 Sep 2020 5 KB first commit for NWP exp
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