0

Im trying to read ntp through streamreader and i find it difficult when fetching time from ph.pool.ntp.org and it gives me an outofboundsexception when i try to run it on timer

heres my code

 Public Function GetNISTTime(ByVal host As String) As DateTime

    Dim timeStr As String = ""

    Try
        Dim reader As New StreamReader(New TcpClient(host, 13).GetStream)
        timeStr = reader.ReadToEnd()
        Console.WriteLine(timeStr.ToString)
        reader.Close()
    Catch ex As SocketException
        Label1.Text = ex.Message
    Catch ex As Exception
        Label1.Text = ex.Message
    End Try

    Dim jd As Integer = Integer.Parse(timeStr.Substring(1, 5))
    Dim yr As Integer = Integer.Parse(timeStr.Substring(7, 2))
    Dim mo As Integer = Integer.Parse(timeStr.Substring(10, 2))
    Dim dy As Integer = Integer.Parse(timeStr.Substring(13, 2))
    Dim hr As Integer = Integer.Parse(timeStr.Substring(16, 2))
    Dim mm As Integer = Integer.Parse(timeStr.Substring(19, 2))
    Dim sc As Integer = Integer.Parse(timeStr.Substring(22, 2))
    Dim Temp As Integer = CInt(AscW(timeStr(7)))

    Return New DateTime(yr + 2000, mo, dy, hr, mm, sc)

End Function

and the host name are loaded in the timer

Label1.Text = GetNISTTime("ph.pool.ntp.org ").ToString

and it is start by a timer.start() in form load.

hie asd
  • 1
  • 1
  • 1
  • Show us what the string is coming back at. – OneFineDay Aug 22 '15 at 19:10
  • @onefineday it does not return a string because it fires up a Exception thrown: 'System.ArgumentOutOfRangeException – hie asd Aug 22 '15 at 19:12
  • @onefineday at the Dim jd as integer ....... – hie asd Aug 22 '15 at 19:13
  • Right, if the string is empty you cannot try to get a substring of nothing. – OneFineDay Aug 22 '15 at 19:15
  • @onefineday so ph.pool.ntp.org are returning an empty result because i try using utcnist.colorado.edu and work but it does not the correct time in the Philippines – hie asd Aug 22 '15 at 19:17
  • If your code catch an exception you don't stop the execution of the Function but continue trying to parse an empty string. Please verify your host connection because, from here, that host is unknown – Steve Aug 22 '15 at 19:19
  • Well all you have to do is check the `timeStr` variable for being empty before trying to use it. – OneFineDay Aug 22 '15 at 19:19
  • @onefineday can u tell me what can of data is this 57256 15-08-22 19:23:41 50 0 0 323.0 UTC(NIST) * – hie asd Aug 22 '15 at 19:24
  • I can tell you what it is: It's a string that seems to contain a date and a time _and some other random data that we have no idea what it means because we didn't create it, and we have no idea where it came from._ – Visual Vincent Aug 22 '15 at 20:09
  • @VisualVincent this is a standard NTP packet -> https://en.wikipedia.org/wiki/Network_Time_Protocol – JohnKiller Aug 23 '15 at 13:46
  • 1
    @JohnKiller : Okay. :) – Visual Vincent Aug 23 '15 at 20:27

2 Answers2

0
Public Function GetNISTTime(ByVal host As String) As DateTime
    Using sck = New TcpClient(host, 13)
        System.Threading.Thread.Sleep(100) 'give the server time to answer
        Using strm = sck.GetStream
            strm.ReadTimeout = 1000 '1s timeout
            Dim buf(1023) As Byte
            Dim read As Integer = 0
            While read < 50 'loop until enough data is read
                read += strm.Read(buf, read, 1024)
                If read = 0 Then 'connection lost
                    Return Nothing 'or throw exception
                End If
            End While
            Dim rawstring As String = System.Text.Encoding.ASCII.GetString(buf).Trim()
            Dim rawdata As String() = rawstring.Split(" ")
            Dim strdate As String() = rawdata(1).Split("-")
            Dim strtime As String() = rawdata(2).Split(":")
            Return New DateTime(2000 + strdate(0), strdate(1), strdate(2), strtime(0), strtime(1), strtime(2))
        End Using
    End Using
End Function

Instead of using Substring, I've used another approach: Split.

Also I've changed how you read the data from server, since you didn't let the server enough time to provide an answer.

Note that sometimes the server drops the connection instead of sending you the time, so check if the function returns Nothing.

Finally, you better use an NTP library, or at least send the server the expected input.

Interesting related question: How to Query an NTP Server using C#?

Community
  • 1
  • 1
JohnKiller
  • 2,008
  • 18
  • 28
0

I think you have to change a bit

read += strm.Read(buf, read, 1024)

into the

read += strm.Read(buf, read, 1024-read)
Al Imran
  • 882
  • 7
  • 29