001: package org.apache.commons.net.time;
002:
003: /* ====================================================================
004: *
005: * The Apache Software License, Version 1.1
006: *
007: * Copyright (c) 2003 The Apache Software Foundation. All rights
008: * reserved.
009: *
010: * Redistribution and use in source and binary forms, with or without
011: * modification, are permitted provided that the following conditions
012: * are met:
013: *
014: * 1. Redistributions of source code must retain the above copyright
015: * notice, this list of conditions and the following disclaimer.
016: *
017: * 2. Redistributions in binary form must reproduce the above copyright
018: * notice, this list of conditions and the following disclaimer in
019: * the documentation and/or other materials provided with the
020: * distribution.
021: *
022: * 3. The end-user documentation included with the redistribution, if
023: * any, must include the following acknowlegement:
024: * "This product includes software developed by the
025: * Apache Software Foundation (http://www.apache.org/)."
026: * Alternately, this acknowlegement may appear in the software itself,
027: * if and wherever such third-party acknowlegements normally appear.
028: *
029: * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
030: * Foundation" must not be used to endorse or promote products derived
031: * from this software without prior written permission. For written
032: * permission, please contact apache@apache.org.
033: *
034: * 5. Products derived from this software may not be called "Apache"
035: * nor may "Apache" appear in their names without prior written
036: * permission of the Apache Group.
037: *
038: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
039: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
040: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
041: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
042: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
043: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
044: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
045: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
046: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
047: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
048: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
049: * SUCH DAMAGE.
050: * ====================================================================
051: *
052: * This software consists of voluntary contributions made by many
053: * individuals on behalf of the Apache Software Foundation. For more
054: * information on the Apache Software Foundation, please see
055: * <http://www.apache.org/>.
056: */
057:
058: import java.io.DataOutputStream;
059: import java.io.IOException;
060: import java.net.ServerSocket;
061: import java.net.Socket;
062:
063: /**
064: * The TimetSimpleServer class is a simple TCP implementation of a server
065: * for the Time Protocol described in RFC 868.
066: * <p>
067: * Listens for TCP socket connections on the time protocol port and writes
068: * the local time to socket outputStream as 32-bit integer of seconds
069: * since midnight on 1 January 1900 GMT.
070: * See <A HREF="ftp://ftp.rfc-editor.org/in-notes/rfc868.txt"> the spec </A> for
071: * details.
072: * <p>
073: * Note this is for <B>debugging purposes only</B> and not meant to be run as a realiable time service.
074: *
075: * @author Jason Mathews, MITRE Corporation
076: *
077: * @version $Revision: 1.1 $ $Date: 2003/09/24 21:51:48 $
078: */
079: public class TimeTestSimpleServer implements Runnable {
080:
081: /**
082: * baseline time 1900-01-01T00:00:00 UTC
083: */
084: public static final long SECONDS_1900_TO_1970 = 2208988800L;
085:
086: /*** The default time port. It is set to 37 according to RFC 868. ***/
087: public static final int DEFAULT_PORT = 37;
088:
089: private ServerSocket server;
090: private int port;
091: private boolean running = false;
092:
093: /**
094: * Default constructor for TimetSimpleServer.
095: * Initializes port to defaul time port.
096: */
097: public TimeTestSimpleServer() {
098: port = DEFAULT_PORT;
099: }
100:
101: /**
102: * Constructor for TimetSimpleServer given a specific port.
103: */
104: public TimeTestSimpleServer(int port) {
105: this .port = port;
106: }
107:
108: public void connect() throws IOException {
109: if (server == null) {
110: server = new ServerSocket(port);
111: }
112: }
113:
114: public int getPort() {
115: return server == null ? port : server.getLocalPort();
116: }
117:
118: public boolean isRunning() {
119: return running;
120: }
121:
122: /**
123: * Start time service and provide time to client connections.
124: * @throws IOException
125: */
126: public void start() throws IOException {
127: if (server == null) {
128: connect();
129: }
130: if (!running) {
131: running = true;
132: new Thread(this ).start();
133: }
134: }
135:
136: public void run() {
137: Socket socket = null;
138: while (running) {
139: try {
140: socket = server.accept();
141: DataOutputStream os = new DataOutputStream(socket
142: .getOutputStream());
143: // add 500 ms to round off to nearest second
144: int time = (int) ((System.currentTimeMillis() + 500) / 1000 + SECONDS_1900_TO_1970);
145: os.writeInt(time);
146: os.flush();
147: } catch (IOException e) {
148: } finally {
149: if (socket != null)
150: try {
151: socket.close(); // force closing of the socket
152: } catch (IOException e) {
153: System.err.println("close socket error: " + e);
154: }
155: }
156: }
157: }
158:
159: /**
160: * Close server socket.
161: */
162: public void stop() {
163: running = false;
164: if (server != null) {
165: try {
166: server.close(); // force closing of the socket
167: } catch (IOException e) {
168: System.err.println("close socket error: " + e);
169: }
170: server = null;
171: }
172: }
173:
174: public static void main(String[] args) {
175: TimeTestSimpleServer server = new TimeTestSimpleServer();
176: try {
177: server.start();
178: } catch (IOException e) {
179: }
180: }
181:
182: }
|