thongkorn โพสต์ 2018-12-6 14:47:49

[VB.NET] โค้ดการเชื่อมต่อ VPN (Virtual Private Network) และรักษาสถานะการเชื่อมต่อตามเวลาที่เรากำหนด

http://www.g2gnet.com/webboard/images/vbnet/vpn.png

ว่าด้วยเรื่อง VPN หรือ (Virtual Private Network) แอดมินจะอธิบายแบบภาษาบ้านๆ คือ การเชื่อมโยงเครือข่ายภายใน (LAN - Local Area Network) ของเรา ลอดอุโมงค์หรือท่อที่ถูกสร้างขึ้นใหม่ ผ่านทางอินเทอร์เน็ต เพื่อเข้าไปเกาะกลุ่ม LAN อีกวงที่อยู่ระยะห่างไกลได้นั่นเอง ... วิธีการสร้าง VPN Server มีคนเขาอธิบายให้เยอะแยะแล้ว แอดมินจะให้ลิ้งค์เข้าไปอ่านดูก็แล้วกัน เช่น การตั้งค่า VPN (PPTP) แบบ Client to Server บน Windows (มีวิธีการทำ Forward Port ของเน็ต 3BB) และ How to set up a VPN server on Windows 10 (ภาคภาษาอังกฤษ) ... แต่ปัญหาสำหรับ Windows 10 ก็คือ เครื่อง Client จะสามารถเชื่อมต่อเข้ามาได้เพียงทีละ 1 ท่อเท่านั้น หากเราต้องการจะให้มีหลาย Client เข้ามาพร้อมกันได้ ก็ต้องเปลี่ยนไปใช้ Windows Server หรือใช้ Mikrotik แทน อ่านวิธีทำ VPN แบบ PPTP โดยใช้ Mikrotik ...

วิธีการเชื่อมต่อด้วยโค้ด VB.NET ตามที่แอดมินได้เขียนโค้ดไว้ล่วงหน้า ก็จะใช้ 3 วิธีหลักๆ ดังนี้คือ
1. ใช้ Command Line ด้วย Rasdial.exe
2. ใช้ RasPhone
3. ใช้ DotRas (DLL File ของฟรี)

แต่วันนี้แอดมินจะขอนำเสนอวิธีการแรกก่อน เพราะมันง่ายดี และเราไม่จำเป็นต้องไปสร้าง VPN Client ใน Windows ขึ้นมาก่อน ... หลักการของโค้ด ก็คือ สร้าง Phonebook ในการจัดเก็บข้อมูลของการเชื่อมต่อ VPN เอาไว้ จากนั้นก็ทำการสร้าง Batch File เพื่อทำการรันคำสั่ง Rasdial.exe ด้วยการอ่านข้อมูลใน Phonebook อีกที ... ง่ายมั้ยล่ะข่ะรับ แต่ภายใต้ความง่ายนั้น เราจะมองไม่เห็น Error ที่เกิดขึ้นในการเชื่อมต่อ ซึ่งจะไปว่ากันต่อในตอนหน้า

ตัวอย่างของข้อมูลที่อยู่ใน Phonebook ... เราสามารถใช้ Notepad เปิดดูได้เลย

MEDIA=rastapi
Port=VPN2-0
Device=WAN Miniport (IKEv2)
DEVICE=vpn
PhoneNumber=vpndemo
PreviewUserPw=0
เมื่อทำการติดต่อ VPN (กดปุ่ม Connect) ก็จะเกิดการรันคำสั่ง Rasdial.exe ...
http://www.g2gnet.com/webboard/images/vbnet/VPNConnectDos.png

โค้ดในการนับเวลาถอยหลังแบบชั่วโมง-นาที-วินาที ... การเขียนโค้ดเข้าช่วยโดยไม่ใช้คำสั่งสำเร็จรูป หรือคำสั่งภายใน จะช่วยให้เราเร่งเวลาการทำงานให้เร็วขึ้นได้ ด้วยการปรับช่วงเวลา หรือ Interval ของ Timer นั่นเอง เพราะเวลาทำการทดสอบ จะได้ไม่ต้องมานั่งนับเวลาลงตาม Timer แบบเป๊ะๆ เช่น ตั้งการนับถอยหลังลงทุกๆ 10 นาที กว่าจะทดสอบแต่ละครั้งได้นี่ แหม กินเวลานานเกินไปครับ ...
    ' / --------------------------------------------------------------------
    '// การนับถอยหลังโดยคำนวณค่าเวลาแบบชั่วโมง นาที และ วินาที
    Private Function CountDownTime() As String
      'Dim HH As String    '<< ชั่วโมง
      Dim MM As String    '<< นาที
      Dim SS As String    '<< วินาที
      '// 1 ชั่วโมง = 3600 วินาที
      'HH = TimeCount \ 3600

      '// การ Mod ด้วย 3600 ก็คือ 60 นาทีมีค่าเท่ากับ 3600 วินาที (การนับรวมชั่วโมง)
      '// การหารตัดเศษ \ ด้วย 60 คือต้องการแสดงผลในรูปแบบนาที
      MM = (TimeCounter Mod 3600) \ 60

      '// การ Mod ด้วย 60 (ค่าวินาที) จะทำให้ค่าสูงสุดอยู่ที่ 59 วินาที
      SS = (TimeCounter Mod 60)
      '// แสดงผล
      'HH = Microsoft.VisualBasic.Right("00" & HH, 2)
      MM = Microsoft.VisualBasic.Right("00" & MM, 2)
      SS = Microsoft.VisualBasic.Right("00" & SS, 2)
      'Return HH & ":" & MM & ":" & SS
      '// เอาเฉพาะนาที-วินาที
      Return MM & ":" & SS
    End Function
มาดูโค้ดฉบับเต็มกันเถอะ ...
' / --------------------------------------------------------------------
' / Developer : Mr.Surapon Yodsanga (Thongkorn Tubtimkrob)
' / eMail : thongkorn@hotmail.com
' / URL: http://www.g2gnet.com (Khon Kaen - Thailand)
' / Facebook: https://www.facebook.com/g2gnet (For Thailand)
' / Facebook: https://www.facebook.com/commonindy (Worldwide)
' / More: http://www.g2gnet.com/webboard
' /
' / Purpose: Connect VPN (Virtual Private Network) and Re-Connect it.
' / Microsoft Visual Basic .NET (2010)
' /
' / This is open source code under @CopyRight by Thongkorn Tubtimkrob.
' / You can not distribute this code for free. Without the consent of the developer.
' / --------------------------------------------------------------------

Imports System.Net

Public Class frmVPNClient
    '// การนับเวลา
    Private TimeCounter As Integer

    '// กำหนดให้แสดงหรือซ่อน DOS Screen
    Dim blnStart As Boolean = True

    '// กำหนด Path ของ Batch File
    Dim strVpn As String = MyPath(Application.StartupPath)
    '// ค่าคงที่ของชื่อโฟลเดอร์
    Const strFolder As String = "MyVPN"

    ' / --------------------------------------------------------------------
    ' / Start Connect
    Private Sub btnConnect_Click(sender As Object, e As EventArgs) Handles btnConnect.Click
      '// หากไม่พบไดเรคตอรี่ ให้สร้าง Directory (Folder นั่นแหละ) ขึ้นมาใหม่
      If Not IO.Directory.Exists(strVpn & strFolder) Then
            IO.Directory.CreateDirectory(strVpn & strFolder)
      End If
      '// RASDIAL
      'https://docs.microsoft.com/en-us/previous-versions/orphan-topics/ws.10/dd450369(v=ws.10)
      '// Create PhoneBook (pbk extension)
      IO.File.WriteAllText( _
                ( _
                strVpn & strFolder & "\connection.pbk"), _
                "" & vbNewLine & _
                "MEDIA=rastapi" & vbNewLine & _
                "Port=VPN2-0" & vbNewLine & _
                "Device=WAN Miniport (IKEv2)" & vbNewLine & _
                "DEVICE=vpn" & vbNewLine & _
                "PhoneNumber=" & txtHost.Text _
                )

      '// Create BAT File เพื่อให้รันคำสั่ง Rasdial และใช้ข้อมูลใน Phonebook
      IO.File.WriteAllText( _
                ( _
                strVpn & strFolder & "\connection.bat"), _
                "rasdial ""VPN"" " & _
                txtUserName.Text & " " & _
                txtPassword.Text & " /phonebook:" & """" & _
                strVpn & strFolder & "\connection.pbk" & """" _
                )

      Try
            Dim connect As System.Diagnostics.Process
            connect = New System.Diagnostics.Process()
            connect.StartInfo.FileName = strVpn & strFolder & "\connection.bat"
            '// หาก Start Program กำหนดให้ blnStart = True
            If blnStart Then
                connect.StartInfo.WindowStyle = ProcessWindowStyle.Normal
            Else
                '// หากทำการ Re-Connect ให้ซ่อนหน้าจอ DOS
                connect.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
            End If
            '//
            connect.Start()
            connect.WaitForExit()
            btnConnect.Enabled = False
            btnDisconnect.Enabled = True
            'MessageBox.Show("Connect VPN already.")
            lblCounterTimer.Text = "00:00"

            '// TEST
            'Timer1.Interval = 50    '<-- ไว้ทดสอบเพราะจะนับเร็วมาก
            'TimeCounter = 60 '<-- 60 วินาทีไว้ทดสอบ
            '// 1000 ms = 1 Sec. (ตอนทดสอบตั้งค่าไว้สัก 50 จะทำให้เร็วขึ้น)
            Timer1.Interval = 1000
            '// นำค่า 2 หลักแรกใน ComboBox มาคูณ 60
            TimeCounter = Val(Microsoft.VisualBasic.Left(cmbTimer.Text, 2)) * 60
            Timer1.Start()
            cmbTimer.Enabled = False
            connect.Dispose()

      Catch ex As Exception
            MessageBox.Show(ex.Message)
      End Try
    End Sub

    ' / --------------------------------------------------------------------
    '// นับเวลาถอยหลัง
    Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick
      If TimeCounter > 0 Then
            TimeCounter -= 1
            lblCounterTimer.Text = CountDownTime()
      Else
            Timer1.Enabled = False
            '// TEST
            'TimeCounter = 60 '<-- 60 วินาทีไว้ทดสอบ
            TimeCounter = Val(Microsoft.VisualBasic.Left(cmbTimer.Text, 2)) * 60
            Timer1.Start()
            '//MsgBox("Time Out.", vbOKOnly + vbInformation, "Report Status")
            lblCounterTimer.Text = "00:00"
            '// เวลา Re-Connect ทุกๆครั้งจะได้ไม่ต้องแสดงผลหน้าจอ DOS
            blnStart = False
            '// กลับไปสั่งให้ Re-Connect อีกรอบ
            Call btnConnect_Click(sender, e)
      End If
    End Sub

    ' / --------------------------------------------------------------------
    '// การนับถอยหลังโดยคำนวณค่าเวลาแบบชั่วโมง นาที และ วินาที
    Private Function CountDownTime() As String
      'Dim HH As String    '<< ชั่วโมง
      Dim MM As String    '<< นาที
      Dim SS As String    '<< วินาที
      '// 1 ชั่วโมง = 3600 วินาที
      'HH = TimeCount \ 3600

      '// การ Mod ด้วย 3600 ก็คือ 60 นาทีมีค่าเท่ากับ 3600 วินาที (การนับรวมชั่วโมง)
      '// การหารตัดเศษ \ ด้วย 60 คือต้องการแสดงผลในรูปแบบนาที
      MM = (TimeCounter Mod 3600) \ 60

      '// การ Mod ด้วย 60 (ค่าวินาที) จะทำให้ค่าสูงสุดอยู่ที่ 59 วินาที
      SS = (TimeCounter Mod 60)
      '// แสดงผล
      'HH = Microsoft.VisualBasic.Right("00" & HH, 2)
      MM = Microsoft.VisualBasic.Right("00" & MM, 2)
      SS = Microsoft.VisualBasic.Right("00" & SS, 2)
      'Return HH & ":" & MM & ":" & SS
      '// เอาเฉพาะนาที-วินาที
      Return MM & ":" & SS
    End Function

    ' / --------------------------------------------------------------------
    ' / ตัดการเชื่อมต่อ
    Private Sub btnDisConnect_Click(sender As Object, e As EventArgs) Handles btnDisconnect.Click
      IO.File.WriteAllText((strVpn & strFolder & "\disconnect.bat"), "rasdial/d")
      Dim connect As System.Diagnostics.Process
      connect = New System.Diagnostics.Process()
      connect.StartInfo.FileName = strVpn & strFolder & "\disconnect.bat"
      connect.StartInfo.WindowStyle = ProcessWindowStyle.Normal
      '//
      connect.Start()
      connect.WaitForExit()
      btnConnect.Enabled = True
      btnDisconnect.Enabled = False
      '//
      Timer1.Enabled = False
      lblCounterTimer.Text = "00:00"
      cmbTimer.Enabled = True
      blnStart = True
    End Sub

    Private Sub frmVPNClient_FormClosed(sender As Object, e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
      '// จะปิดหรือค้าง Connection เอาไว้ก็เลือกเอาครับ
      'Call btnDisConnect_Click(sender, e)
      '//
      Me.Dispose()
      Application.Exit()
    End Sub

    Private Sub frmVPNConnector_Load(sender As Object, e As System.EventArgs) Handles Me.Load
      txtHost.Text = "YOUR HOST"
      txtUserName.Text = "USERNAME"
      txtPassword.Text = "PASSWORD"
      '//
      lblCounterTimer.Text = ""
      With cmbTimer
            .Items.Add("10 นาที")
            .Items.Add("20 นาที")
            .Items.Add("30 นาที")
            .Items.Add("40 นาที")
            .Items.Add("50 นาที")
            .Items.Add("60 นาที")
      End With
      cmbTimer.SelectedIndex = 0
      lblCounterTimer.Text = "00:00"
    End Sub

    Private Sub cmbTimer_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles cmbTimer.KeyDown
      If e.KeyCode = 13 Then
            e.Handled = True
            SendKeys.Send("{TAB}")
      End If
    End Sub

    Private Sub txtHost_KeyPress(sender As Object, e As System.Windows.Forms.KeyPressEventArgs) Handles txtHost.KeyPress
      If e.KeyChar = Chr(13) Then
            e.Handled = True
            SendKeys.Send("{TAB}")
      End If
    End Sub

    Private Sub txtPassword_KeyPress(sender As Object, e As System.Windows.Forms.KeyPressEventArgs) Handles txtPassword.KeyPress
      If e.KeyChar = Chr(13) Then
            e.Handled = True
            SendKeys.Send("{TAB}")
      End If
    End Sub

    Private Sub txtUserName_KeyPress(sender As Object, e As System.Windows.Forms.KeyPressEventArgs) Handles txtUserName.KeyPress
      If e.KeyChar = Chr(13) Then
            e.Handled = True
            SendKeys.Send("{TAB}")
      End If
    End Sub

    ' / --------------------------------------------------------------------------------
    ' / Get my project path
    ' / AppPath = C:\My Project\bin\debug
    ' / Replace "\bin\debug" with "\"
    ' / Return : C:\My Project\
    Function MyPath(ByVal AppPath As String) As String
      '/ MessageBox.Show(AppPath);
      AppPath = AppPath.ToLower()
      '/ Return Value
      MyPath = AppPath.Replace("\bin\debug", "\").Replace("\bin\release", "\").Replace("\bin\x86\debug", "\").Replace("\bin\x86\release", "\")
      '// If not found folder then put the \ (BackSlash) at the end.
      If Microsoft.VisualBasic.Right(MyPath, 1) <> "\" Then MyPath = MyPath & "\"
    End Function

End Class
ดาวน์โหลดโค้ดต้นฉบับแบบเต็ม VB.NET (2010) ได้ที่นี่ ...
หน้า: [1]
ดูในรูปแบบกติ: [VB.NET] โค้ดการเชื่อมต่อ VPN (Virtual Private Network) และรักษาสถานะการเชื่อมต่อตามเวลาที่เรากำหนด