
import java.io.IOException;
import java.net.InetAddress;
import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;


/**
 * <p>Ping は、ping ツールを模した、Javaプログラムです。<br />
 * ping (というツール) は、ICMP (TCP/IP に含まれるプロトコルのひとつ) で
 * echo request という種類のパケットを送り、それに対して返される
 * echo reply というパケットを受け取ります。</p>
 * 
 * <p>Java の標準 API (Java Platform 1.X Core API) では、ICMP のパケットは扱えません。
 * Pingの目的として、TCP,UDP の 7番ポートの echo というサービスを利用して
 * 対象マシンが稼働しているか確認する、という事です。</p>
 *
 * Usage:java Ping hostname [count] [interval]
 *
 * @see http://java-house.jp/ml/archive/j-h-b/051747.html
 * @see http://java-house.jp/ml/archive/j-h-b/030408.html
 * @see http://java-house.jp/ml/archive/j-h-b/030388.html
 *
 * @version  0.9.0	2001/05/28
 * @author	 Kazuhiko Hasegawa
 * @since	 JDK1.1,
 */
public class Ping {

	/** ポート番号 */
	private static final int PORT = 7;

	/** 初期繰り返し回数 */
	private static final int CNT = 4;

	/** 初期実行間隔 */
	private static final int INTERVAL = 1000;

	/** タイムアウト時間 */
	private static final int TIMEOUT  = 5000;		// TimeOutの設定 [ms]

	/** 送信内容 */
	private static final byte[] data = "12345678901234567890123456789012".getBytes();

	private static final String OK = "[OK] " ;
	private static final String NG = "[NG] " ;

	private final String hostName ;

	private String message = null;

	private DateFormat formatter = new SimpleDateFormat( "yyyy/MM/dd HH:mm:ss" );


	private DatagramSocket socket ;
	private InetAddress    server;
	private DatagramPacket packet;

	public Ping( String hostName ) {
		this.hostName = hostName;
		init();
	}

	private void init() {
		try {
			socket = new DatagramSocket();
			socket.setSoTimeout(TIMEOUT);
			server = InetAddress.getByName( hostName );

			System.out.print( "Pinging " );
			System.out.print( server.getCanonicalHostName() );
			System.out.print( " [" +  server.getHostAddress() + "]" );
			System.out.println( " with " + data.length + " bytes of data:" );
			System.out.println();
			packet = new DatagramPacket( data, data.length,server, PORT );

			message = " Reply from " + server.getHostAddress() + ": bytes=" + data.length + " time=" ;
		}
		catch( UnknownHostException e ) {
			System.err.println( "Server not Found" );
		}
		catch( SocketException e ) {
			System.err.println( "Socket Error" );
		}
		catch( IOException e ) {
			System.err.println( "IO Error" );
		}
		finally {
			if( message == null ) {
				message = " Reply from " + hostName + ": time=" ;
			}
		}
	}

	public void sendPing() {
		if( socket == null ) { init(); }

		String msg1 = OK;
		String msg2 = "";
		long st = System.currentTimeMillis();
		try {
			socket.send( packet );
		}
		catch( NullPointerException e ) {
			msg1 = NG;
			msg2 = " Server not Found" ;
		}
		catch( SocketException e ) {
			msg1 = NG;
			msg2 = " Socket Error" ;
		}
		catch( IOException e ) {
			msg1 = NG;
			msg2 = " IO Error" ;
		}
		finally {
			long end = System.currentTimeMillis();
			System.out.print( msg1 );
			System.out.print( formatter.format(new Date( st )));
			System.out.print( message );
			System.out.print( (end-st) );
			System.out.println( msg2 );
		}
	}

	/** 最初に呼び出されるメソッド */
	public static void main( String[] args ) {
		String host    = null ;
		int    count   = CNT ;
		int    interval= INTERVAL ;

		if( args.length == 0 ) {
			System.err.println("java Ping hostname [count] [interval]");
		}
		if( args.length >= 1 ) {
			host = args[0];
		}
		if( args.length >= 2 ) {
			count = Integer.parseInt( args[1] );
			if( count <= 0 ) { count = Integer.MAX_VALUE ; }
		}
		if( args.length >= 3 ) {
			interval = Integer.parseInt( args[2] );
		}

		Ping ping = new Ping( host );

		for( int i=0; i<count; i++ ) {
			ping.sendPing();
			try {
				Thread.sleep( interval );
			}
			catch ( InterruptedException ex2) { }
		}
	}
}

