본문
안녕하세요 오늘 소개할 내용은 PING테스트 프로그램에 관한 것입니다.
원래 본업은 법원경매 권리분석 등 관련 업무인데
가끔 관련된 업무를 열심히 하다가도 이런 저런 이유로
PC작업에 불편함을 느낄 때가 많습니다.
그중 하나가 다운로드 받거나 기타 실시간 작업을 뭔가 하고 있는데
일시적으로 중단되는 경우가 자주 발생했습니다.
3초 이상 인터넷 신호가 없으면
다시 처음부터 전송하거나 다운받아야 하는
말도 안되는 일들이 종종 있었습니다.
도스(또는 커맨드모드)에서 흔히 핑 때려 보면
응답 없음이 없거나 아주 가끔 발견되었습니다.
좀 더 짧게 자주 신호를 보내면 어떨까?
생각했지만 그런 프로그램은 없더라고요
내가 못찾았을지 모르지만..ㅎㅎ
그래서 그냥 내가 원하는 기능으로 디자인 신경쓰지 않고
원하는 부분만 집어 넣어서 만들어 봤습니다.
원하는 신호와 원하는 값만 불러오겠금 했고
날짜, 시간 등등 기본적인 정보도 표시하게 했고
TTL값 까지만 구현 했습니다.
그러고 보니 cmd 에서 ping 테스트랑 같네요.ㅎ
배경은 검정색 넣었고
텍스트 색은 옥색
처음엔 특정값 이상(50ms)
응답없음 결과 출력될 경우 해당 줄은 다른색으로
표시하겠금 했었는데
삭제하였습니다.ㅎㅎ
내가 원하는 가장 핵심은..
0.1초 단위로 잦은 신호를 보내는 것이었습니다.
그래서
무한으로 계속 신호를 보낼경우
리스트박스 줄이 너무길어지게 되고 느려질걸 방지하기 위해
200줄이 되면 txt파일로 자동 저장 됩니다.
파일명은 저장 싯점의 날짜-시간-분-초.txt 입니다.
사용된 툴은
버튼6개, 리치텍스트박스1개,
라이오버튼 6개
라벨, 링크라벨, 체크박스 입니다.
여기서 리치텍스트박스(richtextbox1)는
좌측 상단 IP주소 입력란인데
그냥 textbox로 해도 무관하지만
좀 더 굵은 글씨와 큰 글씨를
적용하기 위해(서식 적용)
리치텍스트박스를 이용했습니다.
텍스트박스를 이용하지 않은 특별한 기능적 차이는 없습니다.
단지 글씨를 더 크게 ip 주소를 표현하고자 했음
실행 중이더라고 체크박스 체크하면 무조건 상단에 표시됩니다.
실제로 사용된 툴 입니다.
판넬도 있네요..
저건 단지 좌우 여백을 적용하기 위한 목적.
아래는 전체 코드 입니다.
꼼꼼하게 주석 최대한 달아 보려고 노력 했습니다.
귀챠니즘 ㅠㅠ 때문에
기본적인 부분은 생략 했고요..
아래는 전체 코드입니다.
비주얼베이직 2022 무료 공개 버전 이용하였습니다.
Imports System.Net.NetworkInformation
Imports System.Text
Imports System.Threading
Public Class Form1
' Ping 테스트 실행 여부를 저장하는 변수
Dim continuePing As Boolean = False
Dim pingThread As Thread ' Ping을 실행할 스레드
' 프로그램 로드 시 실행되는 이벤트 핸들러
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
RadioButton4.Checked = True ' 기본 핑 간격을 1000ms로 설정
AddHandler CheckBox1.CheckedChanged, AddressOf CheckBox1_CheckedChanged ' CheckBox1 이벤트 핸들러 추가
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) ' 별도 스레드에서 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
' Ping 테스트를 수행하는 함수
Private Sub PingTest()
Dim pingSender As New Ping()
Dim options As New PingOptions() With {.DontFragment = True} ' 패킷 분할 방지 옵션 설정
Dim data As String = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" ' 핑에 포함될 데이터
Dim buffer As Byte() = Encoding.ASCII.GetBytes(data)
Dim timeout As Integer = 120 ' 응답 대기 시간(ms)
Dim reply As PingReply
' 핑 요청을 반복 실행
While continuePing
Dim targetHost As String = String.Empty
Invoke(Sub() targetHost = RichTextBox1.Text) ' UI 스레드에서 RichTextBox1의 값 가져오기
Try
reply = pingSender.Send(targetHost, timeout, buffer, options) ' 핑 요청 실행
Dim result As String
If reply.Status = IPStatus.Success Then
result = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} : {reply.Address}, 응답, 바이트={reply.Buffer.Length}, 시간={reply.RoundtripTime}ms, TTL={reply.Options.Ttl}"
Else
result = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} : {targetHost}, 응답 없음"
End If
' UI 스레드에서 ListBox1에 결과 추가 및 스크롤
Invoke(Sub()
ListBox1.Items.Add(result)
ListBox1.TopIndex = ListBox1.Items.Count - 1
CheckAndSaveListBox() ' 리스트가 일정 개수 이상이면 자동 저장
End Sub)
Catch ex As Exception
' 예외 발생 시 UI에 오류 메시지 출력
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
If RadioButton2.Checked Then Return 200
If RadioButton3.Checked Then Return 500
If RadioButton4.Checked Then Return 1000
If RadioButton5.Checked Then Return 1500
If RadioButton6.Checked Then Return 2000
Return 500 ' 기본값
End Function
' 프로그램 종료 버튼 클릭 시 실행
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
End
End Sub
' ListBox1에서 Ctrl+C로 항목 복사 가능하도록 설정
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
' ListBox1의 내용을 지우는 버튼
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
Dim saveFileDialog As New SaveFileDialog() With {
.FileName = "PingResults.txt",
.Filter = "텍스트 파일 (*.txt)|*.txt|모든 파일 (*.*)|*.*"
}
If saveFileDialog.ShowDialog() = DialogResult.OK Then
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")
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
' CheckBox1 체크 여부에 따라 창을 항상 위에 표시
Private Sub CheckBox1_CheckedChanged(sender As Object, e As EventArgs)
Me.TopMost = CheckBox1.Checked
End Sub
' ListBox 항목이 200개 이상이면 자동 저장 후 초기화하는 함수
Private Sub CheckAndSaveListBox()
If ListBox1.Items.Count >= 200 Then
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)
ListBox1.Items.Clear()
End If
End Sub
' 저장된 파일 경로 열기 버튼
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
코딩하는 목적은
앞서 설명드렸지만
본 업이 법원경매 물건분석, 권리분석, 현장임장 탐문 그런 것들 입니다.
그러한 업무 수행중 불편한 부분이 있으면 그때 그때 만들어 사용합니다.
그래서 일반분들에게는 적용되기 어려운 (사용할 수 없는) 그런 기능들이 많네요
다음 시간에(시간 되면..)
자동 파일이름 수정 프로그램과 소스를 올려보도록 하겠습니다.
(주요기능 : 리스트박스에 파일 드롭하면 파일목록 추가,
폴더를 던지면 폴더 안에 있는 파일들만 목록 추가,
파일명 변경 버튼 클릭시 원본 파일은 건들지 않고
output 폴더 생성 후 변경된 파일명으로 자료 복사)
뭐.. 등등..
지난주 다 만들었는데
이 또한 경매 업무때문에 만들었기에
일반 분들에게는 성격이 안맞지만
코딩 공부하시는 분들이라면
핵심 기능과 함수만 따서 보편적인 기능으로 변환해서 사용 가능하기에
공개하고 있습니다.
초보 코드쟁이들을 위해~ㅎㅎ
'Programming > VB.NET' 카테고리의 다른 글
VB.NET 복사 & 붙여넣기 한글 깨짐 현상 해결 방법 (1) | 2013.05.14 |
---|---|
[VB.NET] PC 재부팅 소스 (0) | 2013.05.07 |
[VB.NET] USB드라이브 찾기 (0) | 2013.04.05 |