View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.net.time;
19  
20  import java.io.DataOutputStream;
21  import java.io.IOException;
22  import java.net.ServerSocket;
23  import java.net.Socket;
24  
25  /**
26   * The TimetSimpleServer class is a simple TCP implementation of a server for the Time Protocol described in RFC 868.
27   * <p>
28   * Listens for TCP socket connections on the time protocol port and writes the local time to socket outputStream as 32-bit integer of seconds since midnight on
29   * 1 January 1900 GMT. See <A HREF="ftp://ftp.rfc-editor.org/in-notes/rfc868.txt"> the spec </A> for details.
30   * <p>
31   * Note this is for <B>debugging purposes only</B> and not meant to be run as a realiable time service.
32   */
33  public class TimeTestSimpleServer implements Runnable {
34  
35      /**
36       * baseline time 1900-01-01T00:00:00 UTC
37       */
38      public static final long SECONDS_1900_TO_1970 = 2208988800L;
39  
40      /** The default time port. It is set to 37 according to RFC 868. */
41      public static final int DEFAULT_PORT = 37;
42  
43      public static void main(final String[] args) {
44          final TimeTestSimpleServer server = new TimeTestSimpleServer();
45          try {
46              server.start();
47          } catch (final IOException e) {
48              // ignored
49          }
50      }
51  
52      private ServerSocket server;
53      private final int port;
54  
55      private boolean running;
56  
57      public TimeTestSimpleServer() {
58          port = DEFAULT_PORT;
59      }
60  
61      public TimeTestSimpleServer(final int port) {
62          this.port = port;
63      }
64  
65      public void connect() throws IOException {
66          if (server == null) {
67              server = new ServerSocket(port);
68          }
69      }
70  
71      public int getPort() {
72          return server == null ? port : server.getLocalPort();
73      }
74  
75      public boolean isRunning() {
76          return running;
77      }
78  
79      @Override
80      public void run() {
81          Socket socket = null;
82          while (running) {
83              try {
84                  socket = server.accept();
85                  final DataOutputStream os = new DataOutputStream(socket.getOutputStream());
86                  // add 500 ms to round off to nearest second
87                  final int time = (int) ((System.currentTimeMillis() + 500) / 1000 + SECONDS_1900_TO_1970);
88                  os.writeInt(time);
89                  os.flush();
90              } catch (final IOException e) {
91                  // ignored
92              } finally {
93                  if (socket != null) {
94                      try {
95                          socket.close(); // force closing of the socket
96                      } catch (final IOException e) {
97                          System.err.println("close socket error: " + e);
98                      }
99                  }
100             }
101         }
102     }
103 
104     /*
105      * Start time service and provide time to client connections.
106      */
107     public void start() throws IOException {
108         if (server == null) {
109             connect();
110         }
111         if (!running) {
112             running = true;
113             new Thread(this).start();
114         }
115     }
116 
117     /*
118      * Close server socket.
119      */
120     public void stop() {
121         running = false;
122         if (server != null) {
123             try {
124                 server.close(); // force closing of the socket
125             } catch (final IOException e) {
126                 System.err.println("close socket error: " + e);
127             }
128             server = null;
129         }
130     }
131 
132 }