어떻게 Windows API 를 사용 하여 IP, MAC 를 가 져 옵 니까?

여기 서 사용 하 는 두 가지 함수: gethostby name / gethostby addr, GetAdapters Info, 여 기 는 주로 IP 를 가 져 와 링크 를 보 는 동작 입 니 다.
모든 IP 주 소 를 가 져 오 는 함 수 는 다음 과 같 습 니 다.
int CIPInfo::GetIPInfo(const char * szHostName)
{
#define HOST_NAME_MAX 256
	char szHost[HOST_NAME_MAX];
	HOSTENT* pHost;
	//LPSTR szIPAddr = NULL;
	char* szIPAddr = NULL;
	in_addr addr;
	memset(szHost, 0, ARRSIZE(szHost));

	if (szHostName)
	{
		if (isalpha(szHostName[0]))  /* host address is a name */
		{     
#ifdef _DEBUG
			TRACE("Calling gethostbyname with %s
", szHostName); #endif // _DEBUG pHost = gethostbyname(szHostName); } else if (isdigit(szHostName[0])) /* host address is a digit */ { #ifdef _DEBUG TRACE("Calling gethostbyaddr with %s
", szHostName); #endif // _DEBUG addr.s_addr = inet_addr(szHostName); if (addr.s_addr == INADDR_NONE) { #ifdef _DEBUG TRACE("The IPv4 address entered must be a legal address
"); #endif // _DEBUG return -1; } else { pHost = gethostbyaddr((char *) &addr, 4, AF_INET); } } else { TRACE("The IPv4 address entered Error!
"); return -1; } } else { ::gethostname(szHost, HOST_NAME_MAX); pHost = gethostbyname(szHost); } if (pHost->h_addrtype == AF_INET) { int i = 0; //char *p = NULL; while ( (szIPAddr = pHost->h_addr_list[i]) != 0) //Addresses are in network byte order { memcpy(&addr.s_addr, szIPAddr, pHost->h_length); szIPAddr = ::inet_ntoa(addr); #ifdef _DEBUG TRACE("\tIPv4 Address #%d: %s
", i, szIPAddr); #endif // _DEBUG if (szIPAddr) { PIPInfo ipInfo = GetIPObj(szIPAddr); if (ipInfo) { InsertIPObj(*ipInfo); } } i++; } } else if (pHost->h_addrtype == AF_INET6) { #ifdef _DEBUG TRACE("\tRemotehost is an IPv6 address
"); #endif // _DEBUG return -1; } return 0; }
주의:
1) 여기 서 나 는 IP6 를 제외 하고 IP4 만 사용 했다.
 2) 또 하 나 는 유 니 코드 와 ANSI 문자 집합 I 인 코딩 에 관련 된 문제 입 니 다. 이 규칙 을 엄 격 히 지 키 지 않 았 습 니 다.
3) ip 주소 와 도 메 인 이름 방식 을 사 용 했 습 니 다. 이 함수 에는 기본 적 인 인삼 이 있 기 때 문 입 니 다.
  HOSTENT 를 사용 하여 얻 은 구조 에서 이 컴퓨터 의 ip 주 소 를 포함 하 는 목록 은 h 입 니 다.addr_list, 여기 서 나 는 그것 을 다음 과 같은 구조 링크 에 저장 했다.
typedef struct IPInfo
{	
	char	ip[IP_ADDR_SIZE];
	IPInfo*	next;
}IPInfo, *PIPInfo;
여 기 는 메모리 공간의 개척 과 방출, 링크 의 삽입 과 삭제 가 필요 합 니 다. 여 기 는 제 가 클래스 에 기록 한 함수 이기 때문에 석조 함수 에 방출 할 것 입 니 다.
다음 메모리 공간의 할당
PIPInfo CIPInfo:: GetIPObj(char* szIP)
{
	PIPInfo pIP = (PIPInfo)malloc(sizeof(IPInfo));
	if (pIP)
	{
		memset(pIP->ip, 0, sizeof(pIP->ip));
		strcpy_s( pIP->ip, szIP);
		pIP->next = NULL;
	}
	return pIP;
}
먼저 공간 을 열 고 데 이 터 를 채 웁 니 다. 여 기 는 임시 변수 공간의 방출 을 방지 하기 위해 내용 의 복 제 를 사용 합 니 다.
메모리 공간의 방출: 다음 과 같 습 니 다.
int CIPInfo::FreeIPObj(PIPInfo pIPObj)
{
	if (pIPObj)
	{
		free(pIPObj);
		pIPObj = NULL;
	}
	return 0;
}
공간 을 방출 한 후 에는 반드시 포인 터 를 NULL 로 설정 해 야 합 니 다. 왜 그런 지 참고 하 십시오.
void * 와 빈 포인터 NULL 
링크 삽입: 다음 과 같 습 니 다.
int CIPInfo::InsertIPObj(IPInfo& pIPObj)
{
	PIPInfo pTest = m_ipAddrList;
	if (m_ipAddrList == NULL)
	{
		m_ipAddrList = &pIPObj;
	}
	else
	{
		while ( pTest->next != NULL)
		{
			pTest = pTest->next;
		}

		pTest->next = &pIPObj;			
	}
	return 0;
}
여기 mipAddrList 는 클래스 의 구성원 변수 입 니 다. 여기 링크 는 머리 노드 도 없고 머리 포인터 나 꼬리 포인터 도 없 으 며 단 방향 링크 만 있 습 니 다.링크 가 비어 있 습 니 다. 직접 삽입 합 니 다.링크 가 비어 있 지 않 습 니 다. 끝 에 삽입 합 니 다.
링크 삭제: 다음 과 같 습 니 다:
int CIPInfo::RemoveIPObj(PIPInfo pIPObj)
{
	PIPInfo pTest = m_ipAddrList;
	if (pIPObj == NULL)
	{
		return -1;
	}
	else if (pIPObj == pTest)
	{
		m_ipAddrList = (pTest->next) ? pTest->next : NULL;
	}
	else
	{
		while ( (pTest->next != NULL) &&
			    (pTest->next != pIPObj) )
		{
			pTest = pTest->next;
		}
		if (pTest != NULL)
		{
			pTest->next = (pIPObj->next) ? pIPObj->next : NULL;
		}
	}
	return 0;
}
여기 서 링크 가 비어 있 는 상황 을 고려 해 야 한다. 보통 제거 할 때 판단 한다. 여 기 는 안전 한 것 일 뿐이다. 만약 에 비어 있 지 않 으 면 삭 제 된 것 이 두 결점 인지, 하나의 결점 만 있 는 지, 그 당시 에 다른 요 소 를 삭제 한 것 이 끝 점 인지, 그리고 중간 에 있 는 결점 인지 고려 해 야 한다.
MAC 주소 의 획득 은 설명 되 지 않 습 니 다. 다음 과 같 습 니 다.
int CIPInfo::GetMac(void)
{
	//PIP_ADAPTER_INFO pAdapterInfo = NULL;
	ULONG uLen = 0;

	/*         ,        */
	if (GetAdaptersInfo(pAdapterInfo, &uLen) == ERROR_BUFFER_OVERFLOW) 
	{
		pAdapterInfo = (PIP_ADAPTER_INFO)::GlobalAlloc(GPTR, uLen); //      ,     0
		if (pAdapterInfo == NULL) 
		{
			TRACE("Error allocating memory needed to call GetAdaptersinfo
"); return -1; } } /* */ if ( ::GetAdaptersInfo(pAdapterInfo, &uLen) == ERROR_SUCCESS ) { if (pAdapterInfo) { memcpy(m_szLocalMac, pAdapterInfo->Address, MAC_ADDR_SIZE); strcpy_s(m_szLocalIP, pAdapterInfo->IpAddressList.IpAddress.String); strcpy_s(m_szMask, pAdapterInfo->IpAddressList.IpMask.String); strcpy_s(m_szGatewayIP, pAdapterInfo->GatewayList.IpAddress.String); } } return 0; }
또한 메모리 공간의 방출 을 잊 지 마 세 요. 분 배 된 공간 을 방출 하지 않 으 면 메모리 가 유출 될 수 있 기 때문에 다음 과 같은 분석 함수 입 니 다.
CIPInfo::~CIPInfo(void)
{
	PIPInfo pTest = m_ipAddrList;
	while (pTest)
	{
		RemoveIPObj(pTest);
		FreeIPObj(pTest);
		pTest = m_ipAddrList->next;
	}
	m_ipAddrList = NULL;

	if (pAdapterInfo)
		GlobalFree(pAdapterInfo);	
}

테스트 용례: 여기 MFC 의 주 창 클래스 를 사 용 했 습 니 다. 편집 상자 에 표 시 됩 니 다. 다음 테스트 코드 는 다음 과 같 습 니 다.
void CSocketDlg::OnBnClickedOk()
{
	// TODO:               
	CString strText = _T("");
	CString strTemp = _T("");	
	CIPInfo ipInfo;
	int nIndex = -1;

	nIndex = m_comboBox.GetCurSel();	
	m_comboBox.GetLBText(nIndex, strText);	
		
	if (strText == _T("  IP  "))
	{	
		strText += _T("\r
"); PIPInfo IPInfoList; int nResult = -1; nResult = ipInfo.GetIPInfo(); if( !nResult ) { IPInfoList = ipInfo.GetIPList(); while ( IPInfoList && (strTemp = (CString)IPInfoList->ip)) { strTemp += _T("\r
"); strText += strTemp; IPInfoList = IPInfoList->next; } } } if (strText == _T(" MAC ")) { strText += _T("\r
"); ipInfo.GetMac(); strTemp.Format(_T("IP\t: %s\r
"), (CString)ipInfo.GetLocalIP()); strText += strTemp; strTemp.Format(_T("Mask\t: %s\r
"), (CString)ipInfo.GetMask()); strText += strTemp; strTemp.Format(_T("Gateway\t: %s\r
"),(CString)ipInfo.GetGatewayIP()); strText += strTemp; u_char* p = ipInfo.GetLocalMac(); strTemp.Format(_T("MAC\t: %.2X-%.2X-%.2X-%.2X-%.2X-%.2X"), p[0],p[1],p[2],p[3],p[4],p[5]); strText += strTemp; } SetDlgItemText(IDC_SHOW_TEXT, strText); //CDialogEx::OnOK(); }
IP 테스트 결 과 는 다음 과 같다.
호스트 IP 주소 192.168.1.3 192.168.50.0.1 192.168.159.1
MAC 설정 정 보 를 테스트 한 결 과 는 다음 과 같 습 니 다.
호스트 MAC 주소 IP                : 192.168.1.3 Mask          : 255.255.255.0 Gateway    : 192.168.1.1 MAC            : 9C-4E-36-17-AA-A4

좋은 웹페이지 즐겨찾기