NTPサーバから時間を得る


VB Tips And Sample(HOME)(VB.NET Sample インデックス)



Imports System.Net.Sockets ’こいつをインポートしておきます。
Imports System.Text.Encoding
Public Class Form1

    Inherits System.Windows.Forms.Form

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim ret As Date
        ret = DoSocketNTPTime("130.69.251.23") '東京大学のNTPサーバ
        Debug.WriteLine(ret)
        Me.Label1.Text = CStr(ret)
    End Sub
    Public Function DoSocketNTPTime(ByVal server As String) As Date
'MSDNにのっているソケットのサンプルコードを改造↓
        'Sets up variables and a string to write to the server
        Dim ASCII As System.Text.Encoding = System.Text.Encoding.ASCII

        Dim ByteGet(47) As Byte
        ByteGet(0) = &HB
        Dim RecvBytes(50) As Byte
        Dim strRetPage As String = Nothing

        ' IPAddress and IPEndPoint represent the endpoint that will
        '   receive the request.
        ' Gets the first IPAddress in the list using DNS.
        Dim hostadd As System.Net.IPAddress = System.Net.Dns.Resolve(server).AddressList(0)
        Dim EPhost As New System.Net.IPEndPoint(hostadd, 123)

        'Creates the Socket for sending data over UDP.
        'UDPの場合はSocketType.Dgram
        Dim s As New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)

+αTips
WindowsXPが使用している 123のポートから投げて123で取得する方法。
サービスの「Windows Time」を停止しておきます。123使用中のPGを停止すればよい。
停止しないと、「"通常、各ソケット アドレスに対してプロトコル、ネットワーク アドレス、またはポートのどれか 1 つのみを使用できます。"」
のエラーが出る。因みに2005でも2002でも同じ。
Dim loip = "貴方のPCローカルIP"
Dim loho As System.Net.IPAddress = System.Net.Dns.Resolve(loip).AddressList(0)
Dim Elhost As New System.Net.IPEndPoint(loho, 123)

ソケットを作るところはここは同じ
'Creates the Socket for sending data over UDP.
'UDPの場合はSocketType.Dgram
Dim s As New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
ローカルIP ポート をソケットにバインドしてやる。でOK
s.Bind(Elhost)
        ' Connects to the host using IPEndPoint.
        s.Connect(EPhost)
        If Not s.Connected Then
            strRetPage = "Unable to connect to host"
            Return strRetPage
        End If

        ' Sends the GET text to the host
        s.Send(ByteGet)

        ' Receives the page, looping until all bytes are received
        Dim bytes As Int32 = s.Receive(RecvBytes)
        s.Close()

        strRetPage = "Default HTML page on " & server & ":" & ControlChars.CrLf
        strRetPage = strRetPage + ASCII.GetString(RecvBytes, 0, bytes)
'MSDNにのっているソケットのサンプルコードを改造↑
ネットに転がっていたサンプルを改造↓

        '以下日付計算用変数
        '算出する値に適合するのが通貨型のため、通貨型で宣言
        Dim cuDays As Decimal ' Currency      '現在の日にち格納変数
        Dim cuHours As Decimal 'Currency    '現在の時刻(何時か)の格納変数
        Dim cuMinutes As Decimal 'Currency  '現在の分の格納変数
        Dim cuTempSecs As Decimal 'Currency '時間算出用テンポラリ変数
        Dim cuTimeStamp As Decimal

        'テキストに書き出す
        Debug.WriteLine(strRetPage)
        Dim swf As New System.IO.StreamWriter(Application.StartupPath & "\temp.txt")
        swf.BaseStream.Seek(0, IO.SeekOrigin.End)
        swf.WriteLine(strRetPage)
        swf.Close()

        '世界協定時刻時間に変換する(40-43バイト目で判別する ms単位は無視)
        cuTimeStamp = CDec(RecvBytes(40)) * 2 ^ (8 * 3) + CDec(RecvBytes(41)) * 2 ^ (8 * 2) _
                                        + CDec(RecvBytes(42)) * 2 ^ 8 + CDec(RecvBytes(43))

        'NTPサーバから取得した時刻(1900年1月1日からの時間)を1970年1月1日からの基準に合わせる
        cuTimeStamp = cuTimeStamp - 2208988800@

        cuDays@ = cuTimeStamp \ (24 * CLng(60 * 60))        '日付計算(24h×60m×60s) CLngはオーバーフロー対策
        cuTempSecs@ = cuTimeStamp Mod (24 * CLng(60 * 60))  '日付計算からのあまり(つまり本日分経過した秒数)

        cuHours@ = cuTempSecs@ \ (60 * 60)        '時間計算(60m×60s)
        cuTempSecs@ = cuTempSecs@ Mod (60 * 60)   '時間計算からのあまり秒(つまり残りの分数以下)

        cuMinutes@ = cuTempSecs@ \ 60            '何分かの計算
        cuTempSecs@ = cuTempSecs@ Mod 60         '残りが秒

        Dim dtTime As Date
        '算出した結果を日付型変数に代入し、型変換する
        dtTime = CDate(DateAdd("d", cuDays, "1970/01/01") & " " & cuHours & ":" & cuMinutes & ":" & cuTempSecs)

        ''日本時間へ変更(グリニッジ天文台(イギリス)とは9時間の時差がある)、表示
        dtTime = DateAdd("h", 9, dtTime)
        Debug.WriteLine(dtTime)
’ネットに転がっていたサンプルを改造↑


        Return dtTime
    End Function


End Class



VB Tips And Sample(HOME)(VB.NET Sample インデックス)