/// <summary>
        /// This is the 'nuts and bolts' method that queries the server.
        /// </summary>
        /// <returns>A QueryServerResults instance that holds the results of the query.</returns>
        private QueryServerCompletedEventArgs QueryServer()
        {
            QueryServerCompletedEventArgs result = new QueryServerCompletedEventArgs();

            Initialize();
            UdpClient client = null;

            try
            {
                // Configure and connect the socket.
                client = new UdpClient();
                IPEndPoint ipEndPoint = RemoteSNTPServer.GetIPEndPoint();
                client.Client.SendTimeout    = Timeout;
                client.Client.ReceiveTimeout = Timeout;
                client.Connect(ipEndPoint);

                // Send and receive the data, and save the completion DateTime.
                SNTPData request = SNTPData.GetClientRequestPacket(VersionNumber);
                client.Send(request, request.Length);
                result.Data = client.Receive(ref ipEndPoint);
                result.Data.DestinationDateTime = DateTime.Now.ToUniversalTime();

                // Check the data
                if (result.Data.Mode == Mode.Server)
                {
                    result.Succeeded = true;

                    // Call other method(s) if needed
                    if (UpdateLocalDateTime)
                    {
                        UpdateTime(result.Data.LocalClockOffset);
                        result.LocalDateTimeUpdated = true;
                    }
                }
                else
                {
                    result.ErrorData = new ErrorData("The response from the server was invalid.");
                }
                return(result);
            }
            catch (Exception ex)
            {
                result.ErrorData = new ErrorData(ex);
                return(result);
            }
            finally
            {
                // Close the socket
                if (client != null)
                {
                    client.Close();
                }
            }
        }
        /// <summary>
        /// Gets the real local date and time using the default server and the specified timeout.
        /// If there is an error or exception, DateTime.MinValue is returned.
        /// </summary>
        /// <param name="remoteSNTPServer">The server to use.</param>
        /// <param name="timeout">The timeout in milliseconds used for sending and receiving.</param>
        /// <returns>The real local date and time.</returns>
        public static DateTime GetNow(RemoteSNTPServer remoteSNTPServer, int timeout)
        {
            SNTPClient sntpClient = new SNTPClient();

            sntpClient.UpdateLocalDateTime = false;
            sntpClient.RemoteSNTPServer    = remoteSNTPServer;
            sntpClient.Timeout             = timeout;
            QueryServerCompletedEventArgs args = sntpClient.QueryServer();

            if (args.Succeeded)
            {
                return(DateTime.Now.AddSeconds(args.Data.LocalClockOffset));
            }
            else
            {
                return(DateTime.MinValue);
            }
        }
 /// <summary>
 /// Gets the real local date and time using the specified server and a total timeout of 1 second.
 /// If there is an error or exception, DateTime.MinValue is returned.
 /// </summary>
 /// <param name="remoteSNTPServer">The server to use.</param>
 /// <returns>The real local date and time.</returns>
 public static DateTime GetNow(RemoteSNTPServer remoteSNTPServer)
 {
     return(GetNow(remoteSNTPServer, 500));
 }