前言
很多時候,我們可能會圖省事直接調用系統中的ping命令,但這是很不科學的~
廢話不多說,直接上代碼..
.pro文件
在.pro文件末尾添加一行:
LIBS += -liphlpapi -lws2_32
.h文件
在.h文件中加入:
#include <QDebug>
#include <winsock2.h>
#include <iphlpapi.h>
#include <icmpapi.h>
#include <ws2tcpip.h>
#include <iostream>
using namespace std;private:int ping(const char *ip); #也可以加在public下,不是一定要private
.cpp文件:?
// ping函數
int Widget::ping(const char *ip){//通常使用MAKEWORD宏來指定版本,如MAKEWORD(2, 2)表示使用Winsock 2.2版本。WSADATA wsaData;//WSAStartup函數用于初始化Winsock庫,并指定Winsock庫的版本。這個函數需要在使用Winsock庫的其他函數之前調用,而在程序結束時,你需要調用WSACleanup函數來釋放Winsock庫的資源。if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0){qDebug()<<"Error1:"<<WSAGetLastError();return -1;}// 創建socketSOCKET sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);if (sock == INVALID_SOCKET){qDebug()<<"Error2:"<<WSAGetLastError();return -2;}//設置目的地址SOCKADDR_IN dest;dest.sin_family = AF_INET;dest.sin_addr.s_addr = inet_addr(ip);//創建ICMP數據包const int packet_size = 32; //數據包大小,取值范圍 0-65507char packet[packet_size];memset(packet, 0, packet_size); //memset函數通常用于初始化一段內存空間,或者將一段內存空間清空。這句的作用是將packet指向的內存空間清空,以便后續的代碼可以使用這段內存空間來存儲ICMP報文//創建icmp句柄ICMP_ECHO_REPLY reply;HANDLE icmp_handle = IcmpCreateFile();if (icmp_handle == INVALID_HANDLE_VALUE){qDebug()<<"Error3:"<<GetLastError();return -3;}DWORD reply_size = packet_size + 28; //接收到的ICMP回復數據的大小。+28等同于:+sizeof(reply)//發送ICMP數據包int status = IcmpSendEcho(icmp_handle, dest.sin_addr.s_addr, packet, packet_size, NULL, &reply, reply_size, 2000);if (status == 0) //這里status == 0 表示執行失敗,要查看錯誤碼可以查看: reply.Status{qDebug()<<"Error4:"<<GetLastError();return -4;}// Print the responseqDebug()<<"延時:" << reply.RoundTripTime; //查看延時qDebug()<<"包大小:" << reply.DataSize; //查看數據包大小qDebug()<<"TTL值:" << (int)reply.Options.Ttl; //查看ttl值WSACleanup(); //釋放WSAStartupreturn reply.RoundTripTime; //返回延時
}
ping函數調用方法示例:
方法一:
ping("192.168.1.1");
方法二:
QString ip = "192.168.1.1";
ping(ip.toUtf8());
如果要重復執行,可以通過循環重復調用ping函數..
reply.Status狀態碼:
常量名 | 值 | 含義 |
IP_SUCCESS | 0 | 狀態是成功。 |
IP_BUF_TOO_SMALL | 11001 | 答復緩沖區太小。 |
IP_DEST_NET_UNREACHABLE | 11002 | 目標網絡不可達。 |
IP_DEST_HOST_UNREACHABLE | 11003 | 目標主機不可達。 |
IP_DEST_PROT_UNREACHABLE | 11004 | 目的地的協議是遙不可及。 |
IP_DEST_PORT_UNREACHABLE | 11005 | 目標端口不可達。 |
IP_NO_RESOURCES | 11006 | IP資源不足。 |
IP_BAD_OPTION | 11007 | 指定了錯誤的IP選項。 |
IP_HW_ERROR | 11008 | 一個硬件錯誤。 |
IP_PACKET_TOO_BIG | 11009 | 包太大。 |
IP_REQ_TIMED_OUT | 11010 | 請求超時。 |
IP_BAD_REQ | 11011 | 一個壞的請求。 |
IP_BAD_ROUTE | 11012 | 一個糟糕的路線。 |
IP_TTL_EXPIRED_TRANSIT | 11013 | 在傳輸過程中的生存時間(TTL)的過期。 |
IP_TTL_EXPIRED_REASSEM | 11014 | 在碎片重組過程中的生存時間過期。 |
IP_PARAM_PROBLEM | 11015 | 一個參數的問題。 |
IP_SOURCE_QUENCH | 11016 | 數據報到達太快,處理和數據報可能被丟棄。 |
IP_OPTION_TOO_BIG | 11017 | 一個IP選項是太大了。 |
IP_BAD_DESTINATION | 11018 | 一個壞的目的地。 |
IP_GENERAL_FAILURE | 11050 | 一般故障。這個錯誤可以返回一些畸形的ICMP數據包 |