Easy to Learn Java: Programming Articles, Examples and Tips

Start with Java in a few days with Java Lessons or Lectures

Home

Code Examples

Java Tools

More Java Tools!

Java Forum

All Java Tips

Books

Submit News
Search the site here...
Search...
 

Request and/or provide time service, per RFC 868. RFC 868 Java code example - Click here to copy ->>>

   Can't find what you're looking for? Try our search:

Really working examples categorized by API, package, class. You can compile and run our examples right away! Not from source code for Java projects - only working examples! Copy, compile and run!
------------------

Code:

 

package com.ronsoft.books.nio.channels;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.DatagramChannel;
import java.net.InetSocketAddress;
import java.util.Date;
import java.util.List;
import java.util.LinkedList;
import java.util.Iterator;

// This code is deprecated, see TimeClient and TimeServer

/**
 * Request and/or provide time service, per RFC 868.  RFC 868
 * (http://www.ietf.org/rfc/rfc0868.txt) is a very simple time protocol
 * whereby one system can request the current time from another system.
 * It's a very simple protocol, specified nearly 20 years ago, which
 * does not take into account packet transit time or precision of less
 * than one second.  The Network Time Protocol (NTP) is superior but
 * far too complex for demonstration purposes. 
 * Most Linux, BSD and Solaris systems provide RFC 868 time service
 * on port 37.  This simple program will inter-operate with those.
 * The National Institute of Standards and Technology (NIST) operates
 * a public time server at time.nist.gov.
 *
 * This code also implements an RFC 868 listener to provide time
 * service.  On most unix systems, root privileges are required to
 * bind to ports below 1024.  You can either run this code as root
 * or provide another port number with "-l port#".  If you run this
 * server on an alternate port, you can connect from another JVM
 * by supplying the "-p" option to specify the alternate port for
 * requests.
 *
 * Note: The familiar rdate command on unix will probably not work
 * with this server.  Most versions of rdate use TCP rather than UDP
 * to request the time.
 *
 * When run, this program will issue time requests to each hostname
 * given on the command line, then enter a loop to receive packets.
 * If not acting as a server, it will exit when all expected replies
 * have arrived.  Note that some replies may be lost, which means
 * this code may block forever.  If acting as a server, time requests
 * from remote systems will be dispatched as well, in the same loop.
 *
 * The RFC 868 protocol specifies a 32 bit unsigned value be sent,
 * representing the number of seconds since Jan 1, 1900.  The Java
 * epoch begins on Jan 1, 1970 (same as unix) so an adjustment is
 * made by adding or subtracting 2,208,988,800 as appropriate.  To
 * avoid casting shifting an masking, a four-byte slice of an
 * eight-byte buffer is used send/recieve, but then get/putLong()
 * is done on the full eight bytes to get a long value.
 *
 * Created: April 2002
 * @author Ron Hitchens (ron@ronsoft.com)
 * @version $Id: TimeService.java,v 1.4 2002/05/20 07:24:29 ron Exp $
 */
public class TimeService
{
   private static final int DEFAULT_TIME_PORT = 37;
   private static final long DIFF_1900 = 2208988800L;

   // --------------------------------------------------------------

   protected DatagramChannel channel;
   protected boolean listening = false;

   public TimeService (int port)
      throws Exception
   {
      this.channel = DatagramChannel.open();

      if (port != 0) {
         System.out.println ("Listening on port " + port
            + " for time requests");

         channel.socket().bind (new InetSocketAddress (port));
         listening = true;
      }
   }

   // this version never times out
   protected InetSocketAddress receivePacket (DatagramChannel channel,
      ByteBuffer buffer)
      throws Exception
   {
      buffer.clear();

      // receive a 32-bit, big-endian, unsigned value
      return ((InetSocketAddress) channel.receive (buffer));
   }

   public void run (int expect)
      throws Exception
   {
      // allocate a buffer to hold a long value
      ByteBuffer longBuffer = ByteBuffer.allocate (8);

      // assure big-endian (network) byte order
      longBuffer.order (ByteOrder.BIG_ENDIAN);
      // zero the whole buffer to be sure
      longBuffer.putLong (0, 0);
      // position to first byte of the low-order 32 bits
      longBuffer.position (4);

      // slice the buffer, gives view of the low-order 32 bits
      ByteBuffer buffer = longBuffer.slice();   
      int replies = 0;

      while (true) {
         InetSocketAddress sa;

         sa = receivePacket (channel, buffer);

         if (sa == null) {
            // only get here if receivePacket timed out
            if (listening) {
               continue;
            }

            System.out.println ("Time's up, "
               + (expect - replies)
               + " replies never arrived");

            break;
         }

         buffer.flip();

         if (buffer.remaining() == 0) {
            // empty packet, someone requesting our time
            System.out.println ("Time request from "
               + hostInfo (sa));

            serveTimeRequest (sa);
         } else {
            // reply to a time request we sent
            replies++;
            printTime (longBuffer.getLong (0), sa);
         }

         if (expect == 0) {
            // running as pure server, carry on
            continue;
         }

         if (replies == expect) {
            // all request were answered
            System.out.println ("All packets answered");
            expect = 0;

            if ( ! listening) {
               break;
            }
         } else {
            // some haven't shown up yet
            System.out.println ("Received " + replies
               + " of " + expect + " replies");
         }
      }
   }

   // send a time request to the given internet address
   public void requestTime (InetSocketAddress sa)
      throws Exception
   {
      ByteBuffer buffer = ByteBuffer.allocate (1);

      buffer.flip();      // make it empty, see RFC868

      // fire and forget
      channel.send (buffer, sa);
   }

   // print info about a received time reply
   protected void printTime (long remote1900, InetSocketAddress sa)
   {
      long remote = remote1900 - DIFF_1900;
      long local = currentTimeSecs();
      Date remoteDate = new Date (remote * 1000);
      Date localDate = new Date (local * 1000);
      long skew = remote - local;

      System.out.println ("Reply from " + hostInfo (sa));
      System.out.println ("  there: " + remoteDate);
      System.out.println ("   here: " + localDate);
      System.out.print ("   skew: ");

      if (skew == 0) {
         System.out.println ("none");
      } else {
         System.out.println (skew + " seconds "
            + ((skew < 0) ? "behind" : "ahead"));
      }
   }

   // send the local time to the remote requestor
   protected void serveTimeRequest (InetSocketAddress sa)
      throws Exception
   {
      ByteBuffer buffer = ByteBuffer.allocate (8);

      buffer.clear();
      buffer.putLong (0, currentTimeSecs() + DIFF_1900);
      buffer.position (4);      // low-order 32-bit int

      this.channel.send (buffer, sa);
   }

   // get the local time as seconds since Jan 1, 1970
   public static long currentTimeSecs()
   {
      return (System.currentTimeMillis() / 1000);   // secs/1970
   }

   // convenience formatting method
   public static String hostInfo (InetSocketAddress sa)
   {
      return (sa.getHostName() + ":" + sa.getPort());
   }

   // --------------------------------------------------------------

   public static TimeService newInstance (int listenPort)
      throws Exception
   {
      return (new TimeService (listenPort));
   }

   public static void main (String [] argv)
      throws Exception
   {
      if (argv.length == 0) {
         System.out.println ("Usage: [ -s | -l port ] [ -p port ] host ...");
         return;
      }

      List hosts = new LinkedList();
      int listenPort = 0;
      int port = DEFAULT_TIME_PORT;

      for (int i = 0; i < argv.length; i++) {
         String arg = argv [i];

         // listen as a server, on the default port
         if (arg.equals ("-s")) {
            listenPort = DEFAULT_TIME_PORT;
            continue;
         }

         // listen as a server, on the given port
         if (arg.equals ("-l")) {
            i++;
            listenPort = Integer.parseInt (argv [i]);
            continue;
         }

         // send client requests to the given port
         if (arg.equals ("-p")) {
            i++;
            port = Integer.parseInt (argv [i]);
            continue;
         }

         // create an address object for the host name
         InetSocketAddress sa = new InetSocketAddress (arg, port);

         // validate that it has an address
         if (sa.getAddress() == null) {
            System.out.println ("Cannot resolve address: "
               + arg);

            continue;
         }

         hosts.add (sa);
      }

      TimeService timeService = newInstance (listenPort);

      // send time requests to all the supplied hosts
      Iterator it = hosts.iterator();

      while (it.hasNext()) {
         InetSocketAddress sa = (InetSocketAddress) it.next();

         System.out.println ("Requesting time from "
            + hostInfo (sa));

         timeService.requestTime (sa);
      }

      System.out.println ("");
      System.out.println ("Waiting for replies...");

      timeService.run (hosts.size());
   }
}


 
 



References.

The list of classes which were used on this page you can find below. The links to Java API contain official SUN documentation about all used classes.

  java.nio.channels.DatagramChannel

  org.omg.CORBA.Request

  java.sql.Time

  java.lang.Exception

  java.net.InetSocketAddress

  java.nio.ByteBuffer

  java.sql.Date

  java.awt.List

  java.util.LinkedList

  java.util.Iterator




[ Go Back ]



Home Code Examples Java Forum All Java Tips Books Submit News, Code... Search... Offshore Software Tech Doodling

RSS feed Java FAQ RSS feed Java FAQ News     

    RSS feed Java Forums RSS feed Java Forums

All logos and trademarks in this site are property of their respective owner. The comments are property of their posters, all the rest 1999-2006 by Java FAQs Daily Tips.

Interactive software released under GNU GPL, Code Credits, Privacy Policy