👨💻 안녕하세요, 윌리 프로젝트의 윌리 입니다.
MFC 에서 현재 PC의 네트워크 정보를 알아야 하는 상황이 생겨서, 네트워크 정보를 얻어오는 방법 중 IP_ADAPTER_ADDRESSES 에서 netmask 주소를 얻는 방법에 대해서 알아보았습니다..
질문 >
MFC 에서 IP_ADAPTER_ADDRESSES 에서 netmask 주소를 얻으려면 어떻게 해야 하나요?
답변 >
IP_ADAPTER_ADDRESSES 구조체에서 넷마스크(서브넷 마스크) 주소를 얻으려면 FirstPrefix 멤버를 사용해야 합니다. FirstPrefix는 IP_ADAPTER_PREFIX 구조체의 링크드 리스트를 가리키며, 각 프리픽스는 주소 접두사 길이를 포함합니다. 이 정보를 사용하여 넷마스크를 계산할 수 있습니다.
다음은 MFC 애플리케이션에서 GetAdaptersAddresses를 사용하여 네트워크 어댑터 정보를 가져오고, IP 주소와 서브넷 마스크를 출력하는 예제입니다.
- 필요한 헤더 파일 포함:
#include <afxwin.h>
#include <iphlpapi.h>
#include <vector>
#include <ws2tcpip.h>
#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")
- 네트워크 어댑터 정보를 가져오는 함수 작성:
std::vector<PIP_ADAPTER_ADDRESSES> GetNetworkAdapters() {
std::vector<PIP_ADAPTER_ADDRESSES> adapters;
ULONG outBufLen = 0;
ULONG flags = GAA_FLAG_INCLUDE_PREFIX;
ULONG family = AF_UNSPEC; // For both IPv4 and IPv6 addresses
GetAdaptersAddresses(family, flags, NULL, NULL, &outBufLen);
PIP_ADAPTER_ADDRESSES pAdapterAddresses = (PIP_ADAPTER_ADDRESSES)malloc(outBufLen);
if (pAdapterAddresses == nullptr) {
AfxMessageBox(_T("Error allocating memory needed to call GetAdaptersAddresses"));
return adapters;
}
if (GetAdaptersAddresses(family, flags, NULL, pAdapterAddresses, &outBufLen) == NO_ERROR) {
PIP_ADAPTER_ADDRESSES pAdapter = pAdapterAddresses;
while (pAdapter) {
adapters.push_back(pAdapter);
pAdapter = pAdapter->Next;
}
} else {
AfxMessageBox(_T("GetAdaptersAddresses failed"));
}
return adapters;
}
- IP 주소와 서브넷 마스크를 출력하는 함수 작성:
void PrintNetworkAdapters() {
auto adapters = GetNetworkAdapters();
for (const auto& adapter : adapters) {
CString msg;
msg.Format(_T("Adapter Name: %s\\nDescription: %s\\n"),
adapter->AdapterName,
adapter->Description);
// IP 주소 출력
PIP_ADAPTER_UNICAST_ADDRESS pUnicast = adapter->FirstUnicastAddress;
while (pUnicast != nullptr) {
SOCKADDR *sa = pUnicast->Address.lpSockaddr;
char ipBuf[INET6_ADDRSTRLEN] = { 0 };
char maskBuf[INET6_ADDRSTRLEN] = { 0 };
if (sa->sa_family == AF_INET) {
sockaddr_in *sa_in = (sockaddr_in *)sa;
inet_ntop(AF_INET, &(sa_in->sin_addr), ipBuf, INET6_ADDRSTRLEN);
ULONG prefixLength = pUnicast->OnLinkPrefixLength;
ULONG mask = (0xFFFFFFFF << (32 - prefixLength)) & 0xFFFFFFFF;
sockaddr_in maskAddr;
maskAddr.sin_addr.s_addr = htonl(mask);
inet_ntop(AF_INET, &(maskAddr.sin_addr), maskBuf, INET6_ADDRSTRLEN);
} else if (sa->sa_family == AF_INET6) {
sockaddr_in6 *sa_in6 = (sockaddr_in6 *)sa;
inet_ntop(AF_INET6, &(sa_in6->sin6_addr), ipBuf, INET6_ADDRSTRLEN);
ULONG prefixLength = pUnicast->OnLinkPrefixLength;
for (int i = 0; i < 16; ++i) {
if (prefixLength >= 8) {
maskBuf[i] = 0xFF;
prefixLength -= 8;
} else {
maskBuf[i] = (0xFF << (8 - prefixLength)) & 0xFF;
prefixLength = 0;
}
}
}
msg.AppendFormat(_T("IP Address: %s\\nSubnet Mask: %s\\n"), CString(ipBuf), CString(maskBuf));
pUnicast = pUnicast->Next;
}
AfxMessageBox(msg);
}
// 메모리 해제
for (auto& adapter : adapters) {
free(adapter);
}
}
- 응용 프로그램에서 함수 호출: MFC 애플리케이션의 적절한 위치 (예: 버튼 클릭 이벤트 핸들러)에서 PrintNetworkAdapters 함수를 호출합니다.
void CMyAppDlg::OnBnClickedButtonGetNetworkInfo() {
PrintNetworkAdapters();
}
이 코드는 MFC 애플리케이션에서 GetAdaptersAddresses 함수를 사용하여 네트워크 어댑터 정보를 가져오고, 각 어댑터의 IP 주소와 서브넷 마스크를 계산하여 출력하는 예제입니다. IPv4 주소의 경우 넷마스크를 직접 계산하여 출력하고, IPv6 주소의 경우 접두사 길이를 기반으로 넷마스크를 계산합니다.
🎬 유튜브 채널 🎬
위로그@WiLog
📢 안녕하세요, 위로그@WiLog 시청자 여러분, 저는 윌리 입니다. 📢 위로그@WiLog 는 자기주도학습을 목적으로 라이브 스트리밍을 합니다. 📢 1인 게임 개발을 목표로 Unreal과 Blender를 학습 중입니
www.youtube.com
🎬 치지직 채널 🎬
위로그 채널 - CHZZK
지금, 스트리밍이 시작됩니다. 치지직-
chzzk.naver.com