핑 체크하는 프로그램 만들기 - 개요
네트워크 연결성은 현대 정보화 시대의 핵심 요소로, 다양한 디지털 서비스와 장비는 안정적인 통신 환경을 기반으로 운영됩니다. 특히 연구실, 기업, 산업 현장에서는 서버와 장비 간의 연결 상태를 실시간으로 모니터링하고, 장애 발생 시 즉각적인 대응이 이루어져야 시스템 전체의 안정성이 보장됩니다. 그러나 기존 네트워크 모니터링 솔루션은 복잡한 구성이나 고비용의 상용 소프트웨어에 의존하는 경우가 많아, 단순한 연결 상태 점검을 필요로 하는 사용자에게는 과도한 부담이 될 수 있습니다.
핑(Ping)은 이러한 네트워크 연결 상태를 확인하는 데 가장 기본적이면서도 효과적인 도구로, 대상 장비와의 지연 시간, 패킷 손실 여부 등을 직관적으로 파악할 수 있습니다. 하지만 일반적인 핑 명령어는 단순한 단발성 테스트나 콘솔 기반 확인에 한정되어 있어, 실시간 모니터링·상태 기록·시각화 등 고급 기능이 필요한 경우에는 한계가 존재합니다.
이에 본 프로젝트에서는 여러 장비의 네트워크 상태를 자동으로 측정하고, 결과를 시각적으로 제공하며, 임계값 초과 시 알림 기능까지 포함한 ‘핑 체크 프로그램’을 개발하는 것을 목표로 하였습니다. 또한 간단하고 가벼운 구조를 유지하면서도, 다양한 환경에서 활용할 수 있도록 확장성과 편의성을 고려하여 프로그램을 설계했습니다.
프로젝트의 목표
1. 로컬 디바이스의 실제 IP 주소 자동 탐지 기능 구현
- Docker·WSL·가상환경 등이 아닌 실제 로컬 네트워크 인터페이스의 IP를 반환하도록 설계하였습니다.
- socket 모듈을 활용해 외부 연결을 시도함으로써, 시스템이 사용하는 진짜 로컬 IP를 정확하게 선택합니다.
- 가상 환경에서 발생하는 docker0 또는 172.x.x.x 등의 불필요한 IP가 반환되지 않도록 설계해 네트워크 환경과 프로그램 결과의 일관성을 확보하였습니다.
2. Ping 테스트의 반복 수행 및 정량화된 데이터 수집 기능 제공
- ping3 라이브러리를 기반으로 특정 IP에 대해 지연 시간(RTT)을 다회 반복 측정합니다.
- 각 시도로부터 다음 데이터를 자동 수집
- 시도 번호
- RTT(ms)
- 성공 여부 또는 실패 원인(시간 초과 등)
- 이를 통해 네트워크 품질을 정량적으로 평가할 수 있는 기반 데이터셋이 자동 생성합니다.
3. 측정 결과의 데이터프레임화 및 통계 처리 자동화
- 모든 Ping 결과는 판다스(Pandas) 데이터프레임으로 구조화하여 분석 및 저장에 용이하도록 합니다.
- 성공한 Ping들의 평균 RTT를 자동 계산하여 네트워크 품질에 대한 기초 통계 정보(평균 응답 시간)를 제공합니다.
4. Plotly 기반의 인터랙티브 Ping 시각화 그래프 제공
- Plotly Express를 활용하여 RTT 변동 그래프를 실시간 생성 및 렌더링합니다.
- 기능적 특징
- RTT 변화의 직관적 관찰이 가능한 선 그래프
- Hover 기능을 통한 정확한 수치 확인
- 평균 RTT 기준선 자동 삽입
- Dark 테마 기반의 가독성 높은 UI - 사실 개인 취향
- 이를 통해 단순한 텍스트 기반 Ping 결과가 아닌, 사용자 친화적인 시각 분석 환경을 제공합니다.
5. 네트워크 문제 진단에 적합한 독립 실행형 프로그램 제공
- Docker·가상환경에서의 잘못된 IP 반환 이슈를 해결하고, 반드시 로컬 디바이스에서 실행됨을 전제로 설계하였습니다.
- 단일 실행만으로 IP 탐지 → Ping 실행 → 데이터 수집 → 그래프 출력까지 전 과정이 자동 처리되어 연구실/현장 등에서 즉시 활용 가능하는 것이 최종 목표입니다.
코드
import socket
import ping3
import pandas as pd
import plotly.express as px
import time
def get_local_ip():
"""
로컬 디바이스의 실제 IP 주소를 반환하는 함수입니다.
도커나 WSL 같은 가상 환경에서는 가상 인터페이스의 IP가 반환될 수 있기 때문에,
외부 주소(8.8.8.8)에 소켓을 연결하여 시스템이 실제로 사용하는 네트워크 인터페이스를 확인하는 방식입니다.
"""
s = None
try:
# UDP 소켓을 생성합니다.
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 구글 DNS(8.8.8.8)의 80번 포트로 연결을 시도합니다.
# 실제로 패킷을 보내지는 않지만, OS는 이 연결을 위해 사용 가능한 네트워크 인터페이스를 선택합니다.
s.connect(('8.8.8.8', 80))
# 소켓이 사용 중인 IP 주소를 가져옵니다.
local_ip = s.getsockname()[0]
return local_ip
except Exception:
# 예외 발생 시 hostname 기반의 IP를 반환합니다.
try:
return socket.gethostbyname(socket.gethostname())
except:
# 모든 방법이 실패할 경우 localhost를 반환합니다.
return "127.0.0.1"
finally:
# 소켓이 열려 있으면 닫습니다.
if s:
s.close()
def plotly_ping_and_graph(host, count=15):
"""
특정 host(IP 주소)에 대해 Ping 테스트를 여러 차례 수행하고,
그 결과를 기반으로 Ping 지연 시간 그래프를 생성하는 함수입니다.
host: Ping을 수행할 대상 IP입니다.
count: Ping을 반복 수행할 횟수입니다.
"""
data_list = [] # Ping 결과 데이터를 저장할 리스트입니다.
# ping3 옵션 설정입니다.
# use_global_sock 옵션은 권장되지 않아 제거하였습니다.
ping_options = {'timeout': 2}
print(f"\n[{host}] (로컬 디바이스)에 핑 테스트를 {count}회 시도합니다...")
# count 횟수만큼 반복하여 Ping을 수행합니다.
for i in range(1, count + 1):
# ping3.ping() 함수로 지연 시간을 측정합니다.
delay = ping3.ping(host, **ping_options)
status_text = f"시도 {i}/{count}: "
# Ping 성공 시 delay는 float(초 단위)로 반환됩니다.
if isinstance(delay, float):
rtt_ms = delay * 1000 # 지연 시간을 밀리초 단위로 변환합니다.
# 성공 데이터를 저장합니다.
data_list.append({
'시도 횟수': i,
'지연 시간 (ms)': rtt_ms,
'성공 여부': '성공'
})
print(status_text + f"응답 성공! RTT: {rtt_ms:.5f} ms")
else:
# Ping 실패 시 delay는 None 또는 에러 문자열이 반환됩니다.
fail_reason = "타임아웃" if delay is None else "응답 실패"
data_list.append({
'시도 횟수': i,
'지연 시간 (ms)': None,
'성공 여부': fail_reason
})
# Raw Socket 권한 필요 오류 처리입니다.
if delay == "NeedRootPrivilege":
print("\n\n❌ 치명적 오류 발생: Raw Socket 권한이 필요합니다.")
print("ping3 라이브러리 최신 버전 업데이트 또는 관리자 권한 실행이 필요합니다.")
return False
print(status_text + f"{fail_reason}")
# Ping 사이에 0.5초 간격을 둡니다.
time.sleep(0.5)
# 수집된 데이터를 판다스 데이터프레임으로 변환합니다.
df = pd.DataFrame(data_list)
# 성공한 Ping만 모아 평균 RTT를 계산합니다.
successful_pings = df[df['성공 여부'] == '성공']['지연 시간 (ms)']
if successful_pings.empty:
print(f"\n❌ [{host}] 모든 Ping 시도가 실패했습니다.")
return False
avg_rtt = successful_pings.mean()
# Plotly Express로 지연 시간 그래프를 생성합니다.
fig = px.line(
df.dropna(subset=['지연 시간 (ms)']), # 성공한 데이터만 그래프에 표시합니다.
x='시도 횟수',
y='지연 시간 (ms)',
title=f"로컬 디바이스 Ping 지연 시간 분석: {host}",
markers=True,
color_discrete_sequence=['#1E90FF']
)
# 그래프 레이아웃 설정입니다.
fig.update_layout(
xaxis=dict(
tickmode='linear',
dtick=1,
range=[0.5, count + 0.5]
),
yaxis_title="지연 시간 (ms)",
hovermode="x unified",
template="plotly_dark",
title={
'text': f"로컬 디바이스 Ping 지연 시간 분석: {host}",
'y': 0.95,
'x': 0.5,
'xanchor': 'center',
'yanchor': 'top',
'font': {'size': 24, 'color': 'white'}
},
font={
'family': 'Arial, sans-serif',
'color': 'white'
}
)
# Hover 텍스트 및 선 스타일 설정입니다.
fig.update_traces(
hovertemplate="시도: %{x}<br>지연 시간: %{y:.5f} ms<extra></extra>",
line=dict(shape='spline', smoothing=1)
)
# 평균 RTT를 나타내는 수평선 추가입니다.
fig.add_hline(
y=avg_rtt,
line_dash="dash",
line_color="#FF4500",
annotation_text=f"평균 RTT: {avg_rtt:.5f} ms",
annotation_position="top right"
)
fig.show()
return True
# ------------------------------
# 프로그램 실행 시작 부분입니다.
# ------------------------------
if __name__ == "__main__":
# 로컬 디바이스의 실제 IP 주소를 자동으로 탐지합니다.
local_ip_address = get_local_ip()
print("--- 로컬 디바이스 정보 ---")
print(f"자동 감지된 로컬 IP 주소: {local_ip_address}")
print("----------------------------\n")
# 해당 IP 주소를 대상으로 Ping 테스트를 수행합니다.
plotly_ping_and_graph(local_ip_address, count=15)
- 깃허브 주소 : https://github.com/lko9911/Test_app_ping_check
GitHub - lko9911/Test_app_ping_check
Contribute to lko9911/Test_app_ping_check development by creating an account on GitHub.
github.com
실행 결과

※ 이 코드는 Windows 로컬 환경에서 실제 IPv4 주소를 가져와 Ping 테스트를 수행하는 프로그램입니다.
Docker 환경이나 별도의 컨테이너에서 실행할 경우, 컨테이너 내부의 가상 네트워크 인터페이스(IP)가 반환되므로 정확한 로컬 디바이스 정보를 얻을 수 없습니다.
참고 자료
[컴퓨터 네트워크] 핑 개념
💡 핑 (Ping)의 의미 핑(Ping)은 컴퓨터 네트워크에서 어떤 호스트(Host, 컴퓨터나 서버)가 현재 접속 가능한 상태인지, 그리고 데이터를 주고받는 데 걸리는 시간(지연 시간)이 얼마나 되는지를 확
whitecode2718.tistory.com