1. Preface
When writing remote control using C++, the client often uses the following ten functions to obtain information about the controlled host.
2. Function Modules
1. Obtain the name and IP address of the local computer
#include <iostream> #include <WinSock2.h> #include <WS2tcpip.h> #pragma comment(lib,"ws2_32.lib") #include <iphlpapi.h> #pragma comment(lib,"Iphlpapi.lib") #include <Windows.h> int main() { int wVersionRequested = MAKEWORD(2, 2); WSADATA lpWSAData; WSAStartup(wVersionRequested, &lpWSAData); // Obtain the hostname char szHostName[128]; if (gethostname(szHostName, 128) == 0) { std::cout << "The local computer name is: " << szHostName << std::endl; {} // Obtain the internal IP address struct hostent * pHost; pHost = gethostbyname(szHostName); for (size_t i = 0; pHost != NULL && pHost->h_addr_list[i] != NULL; i++) { std::cout << "The internal IP address is: " << inet_ntoa(*(struct in_addr *)pHost->h_addr_list[i]) << std::endl; {} WSACleanup(); system("pause"); return 0; {}
2. Obtain the local subnet IP address and subnet mask
#include <iostream> #include <atlstr.h> #include <WinSock2.h> #include <WS2tcpip.h> #pragma comment(lib,"ws2_32.lib") #include <iphlpapi.h> #pragma comment(lib,"Iphlpapi.lib") int main() { CString szMark; PIP_ADAPTER_INFO pAdapterInfo = NULL; PIP_ADAPTER_INFO pAdapter = NULL; DWORD dwRetVal = 0; ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO); // The first call to GetAdaptersInfo retrieves the size of ulOutBufLen if (GetAdaptersInfo(NULL, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) { pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen); {} if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) { pAdapter = pAdapterInfo; while (pAdapter) { PIP_ADDR_STRING pIPAddr; pIPAddr = &pAdapter->IpAddressList; while (pIPAddr) { std::cout << "IP: " << pIPAddr->IpAddress.String << std::endl; std::cout << "Mask: " << pIPAddr->IpMask.String << std::endl; std::cout << std::endl; pIPAddr = pIPAddr->Next; {} pAdapter = pAdapter->Next; {} {} if (pAdapterInfo) { free(pAdapterInfo); {} system("pause"); return 0; {}
3. Obtain the physical network card address information of the local machine
#include <iostream> #include <atlstr.h> #include <WinSock2.h> #include <WS2tcpip.h> #pragma comment(lib,"ws2_32.lib") #include <iphlpapi.h> #pragma comment(lib,"Iphlpapi.lib") #include <Windows.h> int main() { PIP_ADAPTER_INFO pAdapterInfo = NULL; PIP_ADAPTER_INFO pAdapter = NULL; DWORD dwRetVal = 0; pAdapterInfo = (IP_ADAPTER_INFO*)malloc(sizeof(IP_ADAPTER_INFO)); ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO); if (GetAdaptersInfo(NULL, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) { pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen); {} if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) { pAdapter = pAdapterInfo; while (pAdapter) { // pAdapter->Description contains "PCI" for physical network card; pAdapter->Type is 71 for wireless network card if (strstr(pAdapter->Description, "PCI") > 0 || pAdapter->Type == 71) { printf("------------------------------\n"); printf("AdapterName: \t%s\n", pAdapter->AdapterName); printf("AdapterDesc: \t%s\n", pAdapter->Description); printf("AdapterAddr: \t"); for (UINT i = 0; i < pAdapter->AddressLength; i++) { printf("%X%c", pAdapter->Address[i], i == pAdapter->AddressLength - 1 ? '\n' : '-'); {} printf("AdapterType: \t%d\n", pAdapter->Type); printf("IPAddress: \t%s\n", pAdapter->IpAddressList.IpAddress.String); printf("IPMask: \t%s\n", pAdapter->IpAddressList.IpMask.String); {} pAdapter = pAdapter->Next; {} {} else { printf("Call to GetAdaptersInfo failed.\n"); {} system("pause"); return 0; {}
4. Get the list and information of all network cards on this computer (including virtual network cards)
#include <iostream> #include <atlstr.h> #include <WinSock2.h> #include <WS2tcpip.h> #pragma comment(lib,"ws2_32.lib") #include <iphlpapi.h> #pragma comment(lib,"Iphlpapi.lib") #include <Windows.h> BOOL GetLocalAdaptersInfo() { //IP_ADAPTER_INFO structure PIP_ADAPTER_INFO pIpAdapterInfo = NULL; pIpAdapterInfo = new IP_ADAPTER_INFO; //Structure size unsigned long ulSize = sizeof(IP_ADAPTER_INFO); //Get adapter information int nRet = GetAdaptersInfo(pIpAdapterInfo, &ulSize); if (ERROR_BUFFER_OVERFLOW == nRet) { //Insufficient space, delete the previously allocated space delete[]pIpAdapterInfo; //Reallocate size pIpAdapterInfo = (PIP_ADAPTER_INFO) new BYTE[ulSize]; //Get adapter information nRet = GetAdaptersInfo(pIpAdapterInfo, &ulSize); //Failed to get if (ERROR_SUCCESS != nRet) { if (pIpAdapterInfo != NULL) { delete[]pIpAdapterInfo; {} return FALSE; {} {} //MAC address information char szMacAddr[20]; //Pointer assignment PIP_ADAPTER_INFO pIterater = pIpAdapterInfo; while (pIterater) { std::cout << "Network card name: " << pIterater->AdapterName << std::endl; std::cout << "Network card description: " << pIterater->Description << std::endl; sprintf_s(szMacAddr, 20, "%02X-%02X-%02X-%02X-%02X-%02X", pIterater->Address[0], pIterater->Address[1], pIterater->Address[2], pIterater->Address[3], pIterater->Address[4], pIterater->Address[5]); std::cout << "MAC Address: " << szMacAddr << std::endl; std::cout << "IP Address List:" << std::endl << std::endl; //Point to the IP address list PIP_ADDR_STRING pIpAddr = &pIterater->IpAddressList; while (pIpAddr) { std::cout << "IP Address: " << pIpAddr->IpAddress.String << std::endl; std::cout << "Subnet Mask: " << pIpAddr->IpMask.String << std::endl; //Point to the gateway list PIP_ADDR_STRING pGateAwayList = &pIterater->GatewayList; while (pGateAwayList) { std::cout << "Gateway: " << pGateAwayList->IpAddress.String << std::endl; pGateAwayList = pGateAwayList->Next; {} pIpAddr = pIpAddr->Next; {} std::cout << std::endl << "--------------------------" << std::endl; pIterater = pIterater->Next; {} //Cleanup if (pIpAdapterInfo) { delete[]pIpAdapterInfo; {} return TRUE; {} int main() { GetLocalAdaptersInfo(); std::cin.get(); system("pause"); return 0; {}
7, Get IP protocol statistics of the local computer
Note:
5, After creating the MFC program, disable the Spectre mitigation in C/C++->Code Generation->Spectre Mitigation, otherwise an error will occur during the code generation later on.
4, If the following error occurs during generation, modify the SDK version in the General settings.
At the beginning of DemoDlg.cpp, include files and reference library files:
#include <Iphlpapi.h> #pragma comment(lib,"IPHlpApi.lib")
The list box control is set to an up and down scroll bar, and the space ID is named IDC_LIST.
The function GetIpStatistics can obtain the statistics of the current host's IP protocol, such as how many packets have been received. The function declaration is as follows:
ULONG GetIpStatistics(PMIB_IPSTATS pStats);
Among them, the parameter pStats points to a pointer of the MIB_IPSTATS structure, which receives the IP statistics of the local computer. If the function succeeds, the return value is NO_ERROR. If the function fails, the return value is the following error code: ·ERROR_INVALID_PARAMETER: The pStats parameter is empty, or GetIpStatistics cannot write to the memory pointed to by the pStats parameter.
The definition of the structure MIB_IPSTATS is as follows:
typedef struct _MIB_IPSTATS { // dwForwarding specifies the forwarding status of each protocol for IPv4 or IPv6, rather than the forwarding status of the interface DWORD dwForwarding; DWORD dwDefaultTTL; //The default initial TTL for packets originating from a specific computer DWORD dwInReceives; //The number of packets received DWORD dwInHdrErrors; //The number of packets received with header errors DWORD dwInAddrErrors; //The number of packets received with address errors DWORD dwForwDatagrams; //The number of forwarded packets DWORD dwInUnknownProtos; //The number of packets received with unknown protocols DWORD dwInDiscards; //The number of received packets discarded DWORD dwInDelivers; //The number of received packets delivered // The number of transmitted packets for IP requests. This number does not include forwarded packets DWORD dwOutRequests; DWORD dwRoutingDiscards; //The number of transmitted packets discarded DWORD dwOutDiscards; //Number of transmitted packets discarded //Number of packets that this computer does not have a route to the target IP address and were discarded DWORD dwOutNoRoutes; //The amount of time allowed for all parts of a fragment packet to arrive. If all data blocks do not arrive within this time, the packet will be discarded DWORD dwReasmTimeout; DWORD dwReasmReqds; //Number of packets that needed to be reassembled DWORD dwReasmOks; //Number of packets successfully reassembled DWORD dwReasmFails; //Number of packets that could not be reassembled DWORD dwFragOks; //Number of packets successfully fragmented //Number of packets that were not fragmented due to an unspecified IP header and were discarded DWORD dwFragFails; DWORD dwFragCreates; //Number of fragments created DWORD dwNumIf; //Number of interfaces DWORD dwNumAddr; //Number of IP addresses associated with this computer DWORD dwNumRoutes; //Number of routes in the IP routing tab } MIB_IPSTATS, *PMIB_IPSTATS;
Double-click the button to add event response code:
void CMFCApplication3Dlg::OnBnClickedButton1() { CListBox* pListBox = (CListBox*)GetDlgItem(IDC_LIST); pListBox->ResetContent(); MIB_IPSTATS IPStats; //获得IP协议统计信息 if (GetIpStatistics(&IPStats) != NO_ERROR) { return; {} CString strText = _T(""); strText.Format(_T("IP forwarding enabled or disabled:%d"), IPStats.dwForwarding); pListBox->AddString(strText); strText.Format(_T("default time-to-live:%d"), IPStats.dwDefaultTTL); pListBox->AddString(strText); strText.Format(_T("datagrams received:%d"), IPStats.dwInReceives); pListBox->AddString(strText); strText.Format(_T("received datagrams discarded:%d"), strText.Format(_T("received header errors:%d"), pListBox->AddString(strText); strText.Format(_T("received address errors:%d"), IPStats.dwInAddrErrors); pListBox->AddString(strText); strText.Format(_T("datagrams forwarded:%d"), IPStats.dwForwDatagrams); pListBox->AddString(strText); strText.Format(_T("datagrams with unknown protocol:%d"), IPStats.dwInUnknownProtos); pListBox->AddString(strText); strText.Format(_T("received datagrams discarded:%d"), IPStats.dwInDiscards); pListBox->AddString(strText); strText.Format(_T("received datagrams delivered:%d"), IPStats.dwInDelivers); pListBox->AddString(strText); strText.Format(_T("outgoing datagrams requested to send:%d"), IPStats.dwOutRequests); pListBox->AddString(strText); strText.Format(_T("outgoing datagrams discarded:%d"), IPStats.dwOutDiscards); pListBox->AddString(strText); strText.Format(_T("sent datagrams discarded:%d"), IPStats.dwOutDiscards); pListBox->AddString(strText); strText.Format(_T("datagrams for which no route exists:%d"), IPStats.dwOutNoRoutes); pListBox->AddString(strText); strText.Format(_T("datagrams for which all frags did not arrive:%d"), IPStats.dwReasmTimeout); pListBox->AddString(strText); strText.Format(_T("datagrams requiring reassembly:%d"), IPStats.dwReasmReqds); pListBox->AddString(strText); strText.Format(_T("successful reassemblies:%d")} IPStats.dwReasmOks); pListBox->AddString(strText); strText.Format(_T("failed reassemblies:%d"), IPStats.dwReasmFails); pListBox->AddString(strText); strText.Format(_T("successful fragmentations:%d"), IPStats.dwFragOks); pListBox->AddString(strText); strText.Format(_T("failed fragmentations:%d"), IPStats.dwFragFails); pListBox->AddString(strText); strText.Format(_T("datagrams fragmented:%d"), IPStats.dwFragCreates); pListBox->AddString(strText); strText.Format(_T("number of interfaces on computer:%d"), IPStats.dwNumIf); pListBox->AddString(strText); strText.Format(_T("number of IP addresses on computer:%d"), IPStats.dwNumAddr); pListBox->AddString(strText); strText.Format(_T("number of routes in routing table:%d"), IPStats.dwNumRoutes); pListBox->AddString(strText); {}
6. Get the DNS address of the local machine
#include <iostream> #include <atlstr.h> #include <WinSock2.h> #include <WS2tcpip.h> #pragma comment(lib,"ws2_32.lib") #include <iphlpapi.h> #pragma comment(lib,"Iphlpapi.lib") #include <Windows.h> int main() { DWORD nLength = 0; //First get the actual size and store it in nLength if (GetNetworkParams(NULL, &nLength) != ERROR_BUFFER_OVERFLOW) { return -1; {} //Allocate space based on the actual required size FIXED_INFO* pFixedInfo = (FIXED_INFO*)new BYTE[nLength]; // Obtain the local computer's network parameters if (GetNetworkParams(pFixedInfo, &nLength) != ERROR_SUCCESS) { delete[] pFixedInfo; return -1; {} //Get the local computer's DNS server address char strText[500] = "Local computer's DNS address:\n"; IP_ADDR_STRING* pCurrentDnsServer = &pFixedInfo->DnsServerList; while (pCurrentDnsServer != NULL) { char strTemp[100] = ""; sprintf(strTemp, "%s\n", pCurrentDnsServer->IpAddress.String); strcat(strText, strTemp); pCurrentDnsServer = pCurrentDnsServer->Next; {} puts(strText); delete[] pFixedInfo; system("pause"); return 0; {}
7. Get TCP statistics on this machine
The space is the same as above, just change the dialog and Caption control name.
This function can be implemented by GetTcpStatistics, which is declared as follows:
ULONG GetTcpStatistics( PMIB_TCPSTATS pStats);
Among them, the parameter pStats points to a pointer of the MIB_TCPSTATS structure, which receives TCP statistics from the local computer. If the function succeeds, the return value is NO_ERROR; if the function fails, the return value is the following error code: ·ERROR_INVALID_PARAMETER: The pStats parameter is empty, or GetTcpStatistics cannot write to the memory pointed to by the pStats parameter.
The structure MIB_TCPSTATS is defined as follows:
typedef struct _MIB_TCPSTATS { DWORD dwRtoAlgorithm; // The retransmission timeout (RTO) algorithm currently in use DWORD dwRtoMin; // The minimum RTO value in milliseconds DWORD dwRtoMax; // The maximum RTO value in milliseconds DWORD dwMaxConn;// The maximum number of connections. If this member is -1, the maximum number of connections is variable // The number of active opens. In active open state, the client is initiating a connection with the server DWORD dwActiveOpens; // The number of passive opens. In passive opens, the server is listening for connection requests from the client DWORD dwPassiveOpens; DWORD dwAttemptFails; // The number of connection attempts that failed DWORD dwEstabResets; // The number of established connections reset DWORD dwCurrEstab; // Number of connections currently established DWORD dwInSegs; // Number of received segments DWORD dwOutSegs; // Number of transmitted segments. This number does not include retransmitted segments DWORD dwRetransSegs; // Number of retransmitted segments DWORD dwInErrs; // Number of received errors DWORD dwOutRsts; // Number of segments transmitted using reset flags // The number of connections currently existing in the system. This total includes all states of connections except for listening connections DWORD dwNumConns; } MIB_TCPSTATS, *PMIB_TCPSTATS;
Double-click the button to add event response code:
void CMFCApplication3Dlg::OnBnClickedButton1() { CListBox* pListBox = (CListBox*)GetDlgItem(IDC_LIST); pListBox->ResetContent(); MIB_TCPSTATS TCPStats; // Obtain TCP protocol statistics if (GetTcpStatistics(&TCPStats) != NO_ERROR) { return; {} CString strText = _T(""); strText.Format(_T("time-out algorithm:%d"), TCPStats.dwRtoAlgorithm); pListBox->AddString(strText); strText.Format(_T("minimum time-out:%d"), TCPStats.dwRtoMin); pListBox->AddString(strText); strText.Format(_T("maximum time-out:%d"), TCPStats.dwRtoMax); pListBox->AddString(strText); strText.Format(_T("maximum connections:%d"), TCPStats.dwMaxConn); pListBox->AddString(strText); strText.Format(_T("active opens:%d"), TCPStats.dwActiveOpens); pListBox->AddString(strText); strText.Format(_T("passive opens:%d"), TCPStats.dwPassiveOpens); pListBox->AddString(strText); strText.Format(_T("failed attempts:%d"), TCPStats.dwAttemptFails); pListBox->AddString(strText); strText.Format(_T("established connections reset:%d"), TCPStats.dwEstabResets); pListBox->AddString(strText); strText.Format(_T("established connections:%d"), TCPStats.dwCurrEstab); pListBox->AddString(strText); strText.Format(_T("segments received:%d"), TCPStats.dwInSegs); pListBox->AddString(strText); strText.Format(_T("segment sent:%d"), TCPStats.dwOutSegs); pListBox->AddString(strText); strText.Format(_T("segments retransmitted:%d"), TCPStats.dwRetransSegs); pListBox->AddString(strText); strText.Format(_T("incoming errors:%d"), TCPStats.dwInErrs); pListBox->AddString(strText); strText.Format(_T("outgoing resets:%d"), TCPStats.dwOutRsts); pListBox->AddString(strText); strText.Format(_T("cumulative connections:%d"), TCPStats.dwNumConns); pListBox->AddString(strText); {}
8、Get UDP statistics on this computer
The space is the same as above, just change the dialog and Caption control name.
This function can be implemented by GetTcpStatistics, which is declared as follows:
ULONG GetUdpStatistics( PMIB_UDPSTATS pStats);
In which, the parameter pStats points to the pointer of MIB_UDPTABLE structure that contains the UDP statistics of the local computer, and PMIB_UDPSTATS is the pointer type of MIB_UDPTABLE structure. If the function succeeds, the return value is NO_ERROR; if the function fails, use FormatMessage to obtain the return error message string.
The structure MIB_UDPSTATS is defined as follows:
typedef struct _MIB_UDPSTATS { DWORD dwInDatagrams; // Number of received data packets DWORD dwNoPorts; // Number of received data packets discarded due to invalid specified ports // Number of error datagrams received. This number does not include the value contained in the dwNoPorts member DWORD dwInErrors; DWORD dwOutDatagrams; // Number of transmitted datagrams DWORD dwNumAddrs; // Number of entries in the UDP listener table } MIB_UDPSTATS,*PMIB_UDPSTATS;
Double-click the button to add event response code:
void CMFCApplication3Dlg::OnBnClickedButton1() { CListBox* pListBox = (CListBox*)GetDlgItem(IDC_LIST); pListBox->ResetContent(); MIB_UDPSTATS UDPStats; // Obtain UDP protocol statistics if (GetUdpStatistics(&UDPStats) != NO_ERROR) { return; {} CString strText = _T(""); strText.Format(_T("received datagrams:%d\t\n"), UDPStats.dwInDatagrams); pListBox->AddString(strText); strText.Format(_T("datagrams for which no port exists:%d\t\n"), UDPStats.dwNoPorts); pListBox->AddString(strText); strText.Format(_T("errors on received datagrams:%d\t\n"), UDPStats.dwInErrors); pListBox->AddString(strText); strText.Format(_T("sent datagrams:%d\t\n"), UDPStats.dwOutDatagrams); pListBox->AddString(strText); strText.Format(_T("number of entries in UDP listener table:%d\t\n"), UDPStats.dwNumAddrs); pListBox->AddString(strText); {}
9. Get the information about network protocols supported on this computer
Include header files and reference library files at the beginning of DemoDlg.cpp:
#include <Winsock2.h> #pragma comment(lib,"Ws2_32.lib")
Add a variable m_ctrlList for the list box control to facilitate inserting information into the list box.
Information about available network transport protocols can be retrieved using the function WSAEnumProtocols. The function is declared as follows:
int WSAAPI WSAEnumProtocols(LPINT lpiProtocols,LPWSAPROTOCOL_INFOA lpProtocolBuffer,LPDWORD lpdwBufferLength);
Among them, the parameter lpiProtocols points to the array of protocol values; lpProtocolBuffer points to the pointer of the buffer filled with the WSAPROTOCOL_INFOA structure; lpdwBufferLength is passed to the lpProtocolBuffer buffer of WSAEnumProtocols when input, which is the number of bytes in the buffer. When output, it can be passed to WSAEnumProtocols to retrieve the minimum buffer size for all requested information. If the function does not occur an error, WSAEnumProtocols will return the number of protocols to report; otherwise, it will return the value of SOCKET_ERROR, and the specific error code can be retrieved by calling WSAGetLastError.
Double-click the button to add event response code:
void CMFCApplication3Dlg::OnBnClickedButton1() { //Initialize WinSock WSADATA WSAData; if (WSAStartup(MAKEWORD(2, 0), &WSAData) != 0) { return; {} int nResult = 0; // Obtain the required buffer size DWORD nLength = 0; nResult = WSAEnumProtocols(NULL, NULL, &nLength); if (nResult != SOCKET_ERROR) { return; {} if (WSAGetLastError() != WSAENOBUFS) { return; {} WSAPROTOCOL_INFO* pProtocolInfo = (WSAPROTOCOL_INFO*)new BYTE[nLength]; //Get local computer protocol information nResult = WSAEnumProtocols(NULL, pProtocolInfo, &nLength); if (nResult == SOCKET_ERROR) { delete[] pProtocolInfo; return; {} for (int n = 0; n < nResult; n++) { m_ctrlList.AddString(pProtocolInfo[n].szProtocol); {} delete[] pProtocolInfo; //Clean up WinSock WSACleanup(); {}
10. Obtain the domain name of the local computer
The function GetNetworkParams can be used to obtain the domain name of the local computer. This function can actually retrieve the network parameters of the local computer, including the domain name, hostname, etc. Of course, if the domain name is not set on this machine, the content of the domain name field obtained will be an empty string.
The function declaration is as follows:
DWORD WINAPI GetNetworkParams( _Out_writes_bytes_opt_(*pOutBufLen) PFIXED_INFO pFixedInfo, _Inout_ PULONG pOutBufLen ;
Among them, the parameter pFixedInfo points to a pointer of a buffer that contains a fixed information structure, which receives the network parameters of the local computer (if the function succeeds). The caller must allocate the correct size buffer before calling the GetNetworkParams function to obtain the content information. If this parameter is NULL, then pOutBufLen can obtain the actual required buffer size; the parameter pOutBufLen points to a pointer of an ULONG variable, which specifies the size of the fixed information structure. If this size is not sufficient to accommodate the information, GetNetworkParams will fill this variable with the required size and return the error code ERROR_BUFFER_OVERFLOW. If the function succeeds, the return value is ERROR_SUCCESS; if the function fails, the return value is the error code.
Double-click the button to add event response code:
void CMFCApplication4Dlg::OnBnClickedButton1() { // Obtain the required buffer size DWORD nLength = 0; if (GetNetworkParams(NULL, &nLength) != ERROR_BUFFER_OVERFLOW) { return; {} FIXED_INFO* pFixedInfo = (FIXED_INFO*)new BYTE[nLength]; // Obtain the local computer's network parameters if (GetNetworkParams(pFixedInfo, &nLength) != ERROR_SUCCESS) { delete[] pFixedInfo; return; {} // Obtain the local computer's domain name CString strText = _T(""); strText.Format(_T("Local computer's domain name: \n%s"), pFixedInfo->DomainName); AfxMessageBox(strText); delete[] pFixedInfo; {}

评论已关闭