본문 바로가기
Coding/Visual Basic

비주얼베이직 PING테스트 프로그램 만들기(Visual Basic Ping Test source)

by 30분전... 2025. 5. 10.

타이틀이에요

 

 

사용 툴 : Visual Basic 2022 무료버전 사용.

혹시 필요하신 분은 아래 MS 공식 홈페이지에서 다운로드 받을 수 있습니다.

https://visualstudio.microsoft.com/ko/downloads/

 

Visual Studio Tools 다운로드 - Windows, Mac, Linux용 무료 설치

Visual Studio IDE 또는 VS Code를 무료로 다운로드하세요. Windows 또는 Mac에서 Visual Studio Professional 또는 Enterprise Edition을 사용해 보세요.

visualstudio.microsoft.com

 

전공 시절 비주얼베이직 언어를 좋아해서 꽤나 오랜시간 관심을 가지고 있었는데요

지금은 거의 비 인기 언어지만

C++에 비교하면 꽤 많은 단점이 있지만

잔머리 잘 돌려가면 상상하는 모든걸 C++ 못지않게 구현 가능합니다.

하지만 정교한 수준의 코딩까지는 필요없고

개인적으로 회사 업무상 그때 그때 필요한 부분이 발생하면

업무 효율을 위해 내 입맛에 맞는 프로그램을 코딩하는데요

쓸데없이 이것 저것 잡다한 코딩들중 

입문하시는 분들 위해 예제 소스로 활용하시라고

포스팅 올립니다.

 


본론입니다.

완성된 모습 실행했을 때 결과값

 

창 조절 가능한 상태로 락은 걸지 않았습니다.

 

디자인이 잘된 수준은 아닙니다.

절대적으로 혼자 사용할 목적이었기 때문입니다.

 

대중성은 전혀 고려하지 않았음.

 

  만든 목적

게임을 하거나, 데이터를 다운로드 받는 상황에서 

가끔 신호가 끊기는 현상을 느꼈습니다.

 

랜카드의 문제인가 싶어 

새로운 랜카드를 구입해 사용했지만

결과는 여전했는데요

그래서 통산사의 문제다 생각했지만

증빙 자료가 필요했습니다.

 

하지만

커맨드모드에서 제공하는 ping테스트 환경은

1초에 1건만 가능합니다.

그래서 미세하게 신호가 잠깐 잠깐 끊기는 

신호는 알 수 없습니다.

도스에서 ping test 모습

 

 

게임을 하다가 신호가 조금 끊긴다?싶으면

단축키 지정해서 바로 실행~

 

 

사용한 툴 (객체)

사용한 객체 리스트

 

주요 객체

1. listbox

2. button1,2,3,4,5,6

3. Checkbox

4. RadioButton1,2,3,4,5,6

5. RichTextBox (굳이 Richtextbox를 사용한 이유는 폰트 사이즈를 크게 조절하기 위함)

 

기타 그외 쓸데없는 기능들

버튼 색깔 조절, 만든이 홈페이지 링크

리스트박스 특성상 줄수가 길어지면 늘어지는 현상으로 인해 200줄 이상 되었을 경우 Txt파일로 저장하고 화면 갱신

 

폼 이벤트

  Dim continuePing As Boolean = False
  Dim pingThread As Thread
  ' Dim CheckBox1 As New CheckBox() ' CheckBox1을 여기서 선언합니다.

  Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
      RadioButton4.Checked = True
      ' CheckBox1의 이벤트 핸들러 추가
      AddHandler CheckBox1.CheckedChanged, AddressOf CheckBox1_CheckedChanged

 

시작 버튼 이벤트

 If Not continuePing Then
     continuePing = True
     pingThread = New Thread(AddressOf PingTest)
     pingThread.IsBackground = True
     pingThread.Start()
 End If

 

 Private Sub PingTest()
     Dim pingSender As New Ping()
     Dim options As New PingOptions()

     options.DontFragment = True

     Dim data As String = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
     Dim buffer As Byte() = Encoding.ASCII.GetBytes(data)
     Dim timeout As Integer = 120
     Dim reply As PingReply

     While continuePing
         Dim targetHost As String = String.Empty

         Invoke(Sub() targetHost = RichTextBox1.Text)

         Try
             reply = pingSender.Send(targetHost, timeout, buffer, options)
             If reply.Status = IPStatus.Success Then
                 Dim result As String = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} : {reply.Address.ToString()}, 응답, 바이트={reply.Buffer.Length}, 시간={reply.RoundtripTime}ms, TTL={reply.Options.Ttl}"
                 Invoke(Sub()
                            ListBox1.Items.Add(result)
                            ListBox1.TopIndex = ListBox1.Items.Count - 1
                            CheckAndSaveListBox()
                        End Sub)
             Else
                 Dim result As String = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} : {targetHost}, 응답 없음"
                 Invoke(Sub()
                            ListBox1.Items.Add(result)
                            ListBox1.TopIndex = ListBox1.Items.Count - 1 
                            CheckAndSaveListBox() 
                        End Sub)
             End If
         Catch ex As Exception
             Invoke(Sub()
                        ListBox1.Items.Add("Ping 요청 실패: " & ex.Message)
                        ListBox1.TopIndex = ListBox1.Items.Count - 1
                        CheckAndSaveListBox()
                    End Sub)
         End Try

         Thread.Sleep(GetPingInterval())
     End While
 End Sub

 

 

라디오버튼 시간 조절

Private Function GetPingInterval() As Integer
    If RadioButton1.Checked Then
        Return 100
    ElseIf RadioButton2.Checked Then
        Return 200
    ElseIf RadioButton3.Checked Then
        Return 500
    ElseIf RadioButton4.Checked Then
        Return 1000
    ElseIf RadioButton5.Checked Then
        Return 1500
    ElseIf RadioButton6.Checked Then
        Return 2000
    Else
        Return 500
    End If
End Function

 

 

리스트박스 선택항목 복사 기능

 Private Sub ListBox1_KeyDown(sender As Object, e As KeyEventArgs) Handles ListBox1.KeyDown
     If e.Control AndAlso e.KeyCode = Keys.C Then
         CopySelectedItemToClipboard()
     End If
 End Sub

 Private Sub CopySelectedItemToClipboard()
     If ListBox1.SelectedItem IsNot Nothing Then
         Clipboard.SetText(ListBox1.SelectedItem.ToString())
     End If
 End Sub

 

 

여기까지가 사실상 핵심 기능입니다.

링크, 정지, 화면갱신 등 자잘한 기능 설명은 하지 않겠습니다.

 

입문하시는 분들 위해 전체 코드 아래 올려놓겠습니다.

 

 

 

전체코드

Imports System.Net.NetworkInformation
Imports System.Text
Imports System.Threading

Public Class Form1
    Dim continuePing As Boolean = False
    Dim pingThread As Thread
    ' Dim CheckBox1 As New CheckBox() ' CheckBox1을 여기서 선언합니다.

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        RadioButton4.Checked = True
        ' CheckBox1의 이벤트 핸들러 추가
        AddHandler CheckBox1.CheckedChanged, AddressOf CheckBox1_CheckedChanged

    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        If Not continuePing Then
            continuePing = True
            pingThread = New Thread(AddressOf PingTest)
            pingThread.IsBackground = True
            pingThread.Start()
        End If
    End Sub

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        continuePing = False
    End Sub
    Private lastSavedFilePath As String = String.Empty
    Private Sub PingTest()
        Dim pingSender As New Ping()
        Dim options As New PingOptions()

        options.DontFragment = True

        Dim data As String = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
        Dim buffer As Byte() = Encoding.ASCII.GetBytes(data)
        Dim timeout As Integer = 120
        Dim reply As PingReply

        While continuePing
            Dim targetHost As String = String.Empty

            ' UI 스레드에서 RichTextBox1의 텍스트 값을 안전하게 읽어옵니다.
            Invoke(Sub() targetHost = RichTextBox1.Text)

            Try
                reply = pingSender.Send(targetHost, timeout, buffer, options)
                If reply.Status = IPStatus.Success Then
                    Dim result As String = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} : {reply.Address.ToString()}, 응답, 바이트={reply.Buffer.Length}, 시간={reply.RoundtripTime}ms, TTL={reply.Options.Ttl}"
                    ' UI 스레드에서 ListBox1에 결과를 추가하고 스크롤을 아래로 이동합니다.
                    Invoke(Sub()
                               ListBox1.Items.Add(result)
                               ListBox1.TopIndex = ListBox1.Items.Count - 1 ' 자동 스크롤
                               CheckAndSaveListBox() ' 리스트 항목 수 확인 및 저장 처리
                           End Sub)
                Else
                    Dim result As String = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} : {targetHost}, 응답 없음"
                    ' UI 스레드에서 ListBox1에 결과를 추가하고 스크롤을 아래로 이동합니다.
                    Invoke(Sub()
                               ListBox1.Items.Add(result)
                               ListBox1.TopIndex = ListBox1.Items.Count - 1 ' 자동 스크롤
                               CheckAndSaveListBox() ' 리스트 항목 수 확인 및 저장 처리
                           End Sub)
                End If
            Catch ex As Exception
                ' UI 스레드에서 ListBox1에 오류 메시지를 추가하고 스크롤을 아래로 이동합니다.
                Invoke(Sub()
                           ListBox1.Items.Add("Ping 요청 실패: " & ex.Message)
                           ListBox1.TopIndex = ListBox1.Items.Count - 1 ' 자동 스크롤
                           CheckAndSaveListBox() ' 리스트 항목 수 확인 및 저장 처리
                       End Sub)
            End Try

            Thread.Sleep(GetPingInterval())
        End While
    End Sub

    Private Function GetPingInterval() As Integer
        If RadioButton1.Checked Then
            Return 100
        ElseIf RadioButton2.Checked Then
            Return 200
        ElseIf RadioButton3.Checked Then
            Return 500
        ElseIf RadioButton4.Checked Then
            Return 1000
        ElseIf RadioButton5.Checked Then
            Return 1500
        ElseIf RadioButton6.Checked Then
            Return 2000
        Else
            Return 500
        End If
    End Function

    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
        End
    End Sub

    Private Sub ListBox1_KeyDown(sender As Object, e As KeyEventArgs) Handles ListBox1.KeyDown
        ' Ctrl+C가 눌렸는지 확인합니다.
        If e.Control AndAlso e.KeyCode = Keys.C Then
            CopySelectedItemToClipboard()
        End If
    End Sub

    Private Sub CopySelectedItemToClipboard()
        ' ListBox에서 선택된 항목이 있는지 확인합니다.
        If ListBox1.SelectedItem IsNot Nothing Then
            ' 선택된 항목의 텍스트를 클립보드에 복사합니다.
            Clipboard.SetText(ListBox1.SelectedItem.ToString())
        End If
    End Sub

    Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
        ListBox1.Items.Clear()

    End Sub

    Private Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click
        ' SaveFileDialog 인스턴스를 생성합니다.
        Dim saveFileDialog As New SaveFileDialog()
        ' 기본 파일 이름과 필터를 설정합니다.
        saveFileDialog.FileName = "PingResults.txt"
        saveFileDialog.Filter = "텍스트 파일 (*.txt)|*.txt|모든 파일 (*.*)|*.*"

        ' SaveFileDialog를 표시하고 사용자가 파일을 저장하기로 결정했는지 확인합니다.
        If saveFileDialog.ShowDialog() = DialogResult.OK Then
            ' ListBox1의 내용을 파일로 저장합니다.
            Using writer As New IO.StreamWriter(saveFileDialog.FileName)
                For Each item As Object In ListBox1.Items
                    writer.WriteLine(item.ToString())
                Next
            End Using
        End If
    End Sub

    Public Sub New()
        ' 이 호출은 디자이너에 필요합니다.
        InitializeComponent()

        ' 링크 라벨 설정
        LinkLabel1.Text = "만든놈 블로그"
        LinkLabel1.Links.Add(0, 10, "https://blog.naver.com/php44")

        ' LinkClicked 이벤트 핸들러 추가
        AddHandler LinkLabel1.LinkClicked, AddressOf LinkLabel1_LinkClicked
    End Sub

    Private Sub LinkLabel1_LinkClicked(sender As Object, e As LinkLabelLinkClickedEventArgs)
        ' 클릭된 링크를 기본 브라우저로 엽니다.
        System.Diagnostics.Process.Start(e.Link.LinkData.ToString())
    End Sub
    Private Sub CheckBox1_CheckedChanged(sender As Object, e As EventArgs)
        ' CheckBox1의 체크 상태에 따라 폼의 TopMost 속성을 설정합니다.
        Me.TopMost = CheckBox1.Checked
    End Sub
    ' 리스트 항목 수가 200건 이상일 때 자동 저장 후 초기화하는 함수
    Private Sub CheckAndSaveListBox()
        If ListBox1.Items.Count >= 200 Then
            ' 현재 시간으로 파일명 생성 (년_월_일_시_분_초.txt)
            Dim timestamp As String = DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss")
            Dim fileName As String = $"{timestamp}.txt"

            ' 파일로 저장
            Using writer As New IO.StreamWriter(fileName)
                For Each item As Object In ListBox1.Items
                    writer.WriteLine(item.ToString())
                Next
            End Using

            ' 저장된 파일 경로를 기억
            lastSavedFilePath = IO.Path.GetFullPath(fileName)

            ' ListBox를 비워서 새 항목을 받을 준비
            ListBox1.Items.Clear()
        End If
    End Sub

    ' Button6_Click 이벤트 핸들러: 저장된 파일 경로 열기
    Private Sub Button6_Click(sender As Object, e As EventArgs) Handles Button6.Click
        If Not String.IsNullOrEmpty(lastSavedFilePath) AndAlso IO.File.Exists(lastSavedFilePath) Then
            ' 파일이 저장된 디렉토리를 탐색기에서 엽니다.
            Dim folderPath As String = IO.Path.GetDirectoryName(lastSavedFilePath)
            System.Diagnostics.Process.Start("explorer.exe", folderPath)
        Else
            MessageBox.Show("저장된 파일이 없습니다.", "오류", MessageBoxButtons.OK, MessageBoxIcon.Warning)
        End If
    End Sub
End Class

 

이해 안되는 부분이나 추가 궁금하신 부분 있으시면 

댓글 남겨주세요.

자주 확인은 못해요. 

본업이 있어서ㅎㅎ

 

빠른 질문과 답변은 주 업무 블로그에 댓글 남기시면 빠른 답 가능합니다.ㅎㅎ

https://m.blog.naver.com/chindole

 

반응형