English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
一つのマシンには複数のネットワークインターフェースが存在する可能性がありますが、各インターフェースには一つのMACアドレスしかなく、各インターフェースは複数のIPアドレスを設定することができます。例えば、一般的なノートパソコンにはワイヤレスネットワークインターフェースと有線ネットワークインターフェース(LANインターフェース)の二種類があります。したがって、このマシンのすべてのネットワークインターフェースのIPとMACアドレス情報を取得するには、各インターフェースを順に取得し、その情報を順に取得する必要があります。Windows SDKでは、IP_ADAPTER_INFO構造体を使用してネットワークインターフェース情報を格納し、インターフェース名、インターフェース説明、インターフェースMACアドレス、インターフェースIPなどが含まれます。この構造体の主な説明は以下の通りです:
typedef struct _IP_ADAPTER_INFO { struct _IP_ADAPTER_INFO* Next;//リストの次のアダプタ情報へのポインタ DWORD ComboIndex;//予備値 char AdapterName[MAX_ADAPTER_NAME_LENGTH + 4];//ANSI文字列で表されるアダプタの名前 char Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4];//ANSI文字列で表されるアダプタの説明 UINT AddressLength;//アダプタのハードウェアアドレスのバイト長 BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH];//BYTE配列で表されるハードウェアアドレス DWORD Index;//アダプタインデックス UINT Type;//アダプタのタイプは以下の通りです: /* * MIB_IF_TYPE_OTHER 1 * MIB_IF_TYPE_ETHERNET 6 * MIB_IF_TYPE_TOKENRING 9 * MIB_IF_TYPE_FDDI 15 * MIB_IF_TYPE_PPP 23 * MIB_IF_TYPE_LOOPBACK 24 * MIB_IF_TYPE_SLIP 28 */ UINT DhcpEnabled;//このアダプタがDHCPを有効にするか指定 PIP_ADDR_STRING CurrentIpAddress;//予備値 IP_ADDR_STRING IpAddressList;//このアダプタのIPv4アドレスリスト IP_ADDR_STRING GatewayList;//このアダプタのゲートウェイIPv4アドレスリスト IP_ADDR_STRING DhcpServer;//このアダプターのDHCPサーバーのIPv4 アドレスリスト BOOL HaveWins; IP_ADDR_STRING PrimaryWinsServer; IP_ADDR_STRING SecondaryWinsServer; time_t LeaseObtained; time_t LeaseExpires; } IP_ADAPTER_INFO,*PIP_ADAPTER_INFO;
複数のネットワークカードがあるため、struct _IP_ADAPTER_INFO* Nextフィールドはリスト構造体のポインタであり、ネットワークカードが複数のIPを持つ場合があるため、IP_ADDR_STRINGフィールドもリスト構造体であるべきです。以下はその情報です:
typedef struct _IP_ADDR_STRING { struct _IP_ADDR_STRING* Next; //同種のノードへのポインタ、つまり次のIP(複数のIPがある場合) IP_ADDRESS_STRING IpAddress; //IPアドレス情報 IP_MASK_STRING IpMask; //IPサブネットマスク DWORD Context;// ネットワークテーブルのエントリ。この値はAddIPAddressとDeleteIPAddress関数のNTEContextパラメータに対応しています。 } IP_ADDR_STRING;
まとめると、以下の図を使ってネットワークカードの構造体の保存情報を説明すると、より明確になるかもしれません:
以上の情報を基本的に理解した後、GetAdaptersInfo関数を呼び出して関連するネットワークカード情報を取得することができます。一般的なコードは以下の通りです:
#include <WinSock2.h> #include <Iphlpapi.h> #include <iostream> using namespace std; #pragma comment(lib,"Iphlpapi.lib") //Iphlpapi.libライブラリを追加する必要があります。 int main(int argc, char* argv[]) { //PIP_ADAPTER_INFO構造体のポインタは、本機のネットワークカード情報を保存します。 PIP_ADAPTER_INFO pIpAdapterInfo = new IP_ADAPTER_INFO(); //構造体のサイズを取得し、GetAdaptersInfoパラメータに使用します。 unsigned long stSize = sizeof(IP_ADAPTER_INFO); //GetAdaptersInfo関数を呼び出し、pIpAdapterInfoポインタ変数を埋める;stSizeパラメータは入力量であり、同時に出力量です int nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize); //ネットワークカードの数を記録する int netCardNum = 0; //各ネットワークカード上のIPアドレスの数を記録する int IPnumPerNetCard = 0; if (ERROR_BUFFER_OVERFLOW == nRel) { //関数がERROR_BUFFER_OVERFLOWを返した場合 //これにより、GetAdaptersInfoパラメータが渡されたメモリ空間が不足していることを示し、stSizeが必要な空間サイズを示しています //これがstSizeが入力量であり、同時に出力量である理由です //元のメモリ空間を解放する delete pIpAdapterInfo; //すべてのネットワークカード情報を格納するためのメモリ空間を再び確保する pIpAdapterInfo = (PIP_ADAPTER_INFO)new BYTE[stSize]; //GetAdaptersInfo関数を再度呼び出し、pIpAdapterInfoポインタ変数を埋める nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize); } if (ERROR_SUCCESS == nRel) { //ネットワークカード情報を出力する //複数のネットワークカードがある可能性があるため、ループを通じて判断する while (pIpAdapterInfo) { cout << "ネットワークカード数:" <<++netCardNum<<endl; cout << "ネットワークカード名:" << pIpAdapterInfo->アダプタ名<<endl; cout << "ネットワークカード説明:" << pIpAdapterInfo->説明<<endl; switch(pIpAdapterInfo->タイプ) { case MIB_IF_TYPE_OTHER: cout << "ネットワークカードタイプ:" << "OTHER" << endl; break; case MIB_IF_TYPE_ETHERNET: cout << "ネットワークカードタイプ:" << "ETHERNET" << endl; break; case MIB_IF_TYPE_TOKENRING: cout << "ネットワークカードタイプ:" << "TOKENRING" << endl; break; case MIB_IF_TYPE_FDDI: cout<<"ネットワークカードのタイプ:"<<"FDDI"<<endl; break; case MIB_IF_TYPE_PPP: printf("PP\n"); cout<<"ネットワークカードのタイプ:"<<"PPP"<<endl; break; case MIB_IF_TYPE_LOOPBACK: cout<<"ネットワークカードのタイプ:"<<"LOOPBACK"<<endl; break; case MIB_IF_TYPE_SLIP: cout<<"ネットワークカードのタイプ:"<<"SLIP"<<endl; break; default: break; } cout<<"ネットワークカードのMACアドレス:"; for (DWORD i = 0; i < pIpAdapterInfo->AddressLength; i++) if (i < pIpAdapterInfo->AddressLength-1) { printf("%02X-", pIpAdapterInfo->Address[i]); } else { printf("%02X\n", pIpAdapterInfo->Address[i]); } cout<<"ネットワークカードのIPアドレス:"<<endl; //ネットワークカードには複数のIPが存在する可能性があるため、ループを使用して判定する IP_ADDR_STRING *pIpAddrString = &(pIpAdapterInfo->IpAddressList); do { cout<<"このネットワークカードのIP数:"<<++IPnumPerNetCard<<endl; cout<<"IPアドレス:"<<pIpAddrString->IpAddress.String<<endl; cout<<"サブネットアドレス:"<<pIpAddrString->IpMask.String<<endl; cout<<"ゲートウェイアドレス:"<<pIpAdapterInfo->GatewayList.IpAddress.String<<endl; pIpAddrString=pIpAddrString->Next; } while (pIpAddrString); pIpAdapterInfo = pIpAdapterInfo->Next; cout<<"--------------------------------------------------------------------"<<endl; } } //メモリを解放する if (pIpAdapterInfo) { delete pIpAdapterInfo; } return 0; }
実行結果:
IPアドレスを取得する第二种方法:
#include <winsock.h> #include <stdio.h> #pragma comment(lib,"ws")2_32.lib") //wsにリンクするために使用されます2_32.libこのライブラリ void CheckIP(void)//CheckIP関数、本機のIPアドレスを取得するために使用されます { WORD wVersionRequested;//WORD型の変数、Winsockバージョンの値を保存するために使用されます WSADATA wsaData; char name[255];//ホスト名を保存するために使用されます PHOSTENT hostinfo; wVersionRequested=MAKEWORD(2,0); //MAKEWORD()関数を呼び出してWinsockバージョンを取得し、Winsockライブラリをロードするために使用します if(WSAStartup(wVersionRequested,&wsaData) == 0) { //Winsockライブラリをロードします。WSAStartup()関数の返値が0の場合、ロードが成功しました if(gethostname(name,sizeof(name))==0) { if((hostinfo = gethostbyname(name) )!= NULL) { //ホスト名を取得した場合、inet_ntoa()関数を呼び出してIPアドレスを取得します LPCSTR ip = inet_ntoa(*(struct in_addr *)*hostinfo->h_addr_list); printf("本機のIPアドレスは:%s\n",ip);//IPアドレスを出力します printf("本機の名前は:%s\n",name); } } WSACleanup(); } } int main() { CheckIP();//CheckIP()関数を呼び出してIPアドレスを取得し、出力します return 0; }
これが編集者が皆様に提供したC++本機のすべてのネットワークカードのIPおよびMACアドレス情報の取得方法の全てを提供しました。皆様のサポートと歓声をどうぞ。