QT實現ping功能
QT實現ping功能
1.問題描述:
- 介面點選“建立連線”按鈕實現測試主機和目的主機的通訊鏈路是否正常。
2.解決思路:
- "建立連線"按鈕響應槽函式,槽函式實現ping操作,返回ping通的結果。
3.解決方法:
方法(1) QProcess呼叫命令列,讀取標準輸出即可。
QProcess物件可以直接執行cmd的命令,但是ping操作是會阻塞的,所以需要在子執行緒裡ping
QProcess *tempCmd = new QProcess();
tempCmd->start(orderInfo);
tempCmd->waitForFinished(1000);//阻塞等待執行命令完成,否則返回的很可能是空字串
QString resultInfo = QString::fromLocal8Bit(tempCmd->readAllStandardOutput());//resultStr就是返回結果,需要fromLocal8Bit來接收中文
方法二(2) 不建議使用QProcess呼叫命令列然後解析返回字串來判斷。我曾經用過這種方法,會程式崩潰。我的程式碼是完全沒問題。後來我是重寫了ping來實現的。就是自己從更底層去實現這個ping,其實程式碼量不大的。原始碼也是有標準的。你拿下來改改就OK
```ctypedef struct tagIPHDR
{
u_char VIHL; // Version and IHL
u_char TOS; // Type Of Service
short TotLen; // Total Length
short ID; // Identification
short FlagOff; // Flags and Fragment Offset
u_char TTL; // Time To Live
u_char Protocol; // Protocol
u_short Checksum; // Checksum
struct in_addr iaSrc; // Internet Address - Source
struct in_addr iaDst; // Internet Address - Destination
}IPHDR, *PIPHDR;
// ICMP Header - RFC 792
typedef struct tagICMPHDR
{
u_char Type; // Type
u_char Code; // Code
u_short Checksum; // Checksum
u_short ID; // Identification
u_short Seq; // Sequence
char Data; // Data
}ICMPHDR, *PICMPHDR;
// ICMP Echo Request
typedef struct tagECHOREQUEST
{
ICMPHDR icmpHdr;
struct timeval echoTime;
char cData[32];
}ECHOREQUEST, *PECHOREQUEST;
// ICMP Echo Reply
typedef struct tagECHOREPLY
{
IPHDR ipHdr;
ECHOREQUEST echoRequest;
char cFiller[256];
}ECHOREPLY, *PECHOREPLY;
bool Utilities::ping(const char *hostName)
{
if (NULL == hostName)
{
XgsLogger::log("", QtWarningMsg, "(%s,%d), Invalid IP address!", __FILE__, __LINE__ );
return false;
}
int sockfd = 0;
int nRet;
int nCount;
int iSuccess = 0;
struct sockaddr_in addrDest;
struct hostent *Dest;
float spenttime;
if ((Dest=gethostbyname(hostName)) == NULL)
{
return false;
}
if((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
{
return false;
}
memset((char *)&addrDest, 0, sizeof(struct sockaddr_in));
addrDest.sin_addr = *((struct in_addr *)Dest->h_addr);
addrDest.sin_family = AF_INET;
bzero(&(addrDest.sin_zero), sizeof( addrDest.sin_zero ) );
ECHOREQUEST echoReq;
memset((ECHOREQUEST*)&echoReq, 0, sizeof(struct tagECHOREQUEST));
echoReq.icmpHdr.Type = ICMP_ECHO;
echoReq.icmpHdr.Code = 0;
echoReq.icmpHdr.ID = getpid();
int Seq = 0;
for (nRet = 0; nRet < 32; nRet++)
echoReq.cData[nRet] = ' '+nRet;
nCount = 0;
while(nCount < 3)
{
echoReq.icmpHdr.Seq = Seq++;
echoReq.icmpHdr.Checksum = 0;
gettimeofday(&echoReq.echoTime,NULL);
echoReq.icmpHdr.Checksum = checksum((unsigned short*)&echoReq, sizeof(struct tagECHOREQUEST));
if (sendto(sockfd, (ECHOREQUEST*)&echoReq, sizeof(tagECHOREQUEST), 0, (struct sockaddr *)&addrDest, sizeof(addrDest)) < 0)
{
close(sockfd);
return false;
}
if(WaitForEchoReply(sockfd) == -1)
{
close(sockfd);
return false;
}
ECHOREPLY icmpRecv;
int addr_len;
addr_len = sizeof(struct sockaddr);
if (recvfrom(sockfd, (ECHOREPLY*)&icmpRecv, sizeof(struct tagECHOREPLY), 0, (struct sockaddr *)&addrDest, (socklen_t *)&addr_len) < 0)
{
close(sockfd);
return false;
}
else if(icmpRecv.echoRequest.icmpHdr.Type == ICMP_ECHOREPLY)
{
gettimeofday(&icmpRecv.echoRequest.echoTime, NULL);
tv_sub(&icmpRecv.echoRequest.echoTime, &echoReq.echoTime);
spenttime=icmpRecv.echoRequest.echoTime.tv_sec*1000+icmpRecv.echoRequest.echoTime.tv_usec*0.001;
if (strcmp(Dest->h_name, inet_ntoa(icmpRecv.ipHdr.iaSrc))==0)
{
iSuccess ++;
// printf("Reply from %s: Bytes=%d Id_seq = %d time=%4.3fms TTL=%d\n",/*Dest->h_name*/inet_ntoa(icmpRecv.ipHdr.iaSrc), sizeof(icmpRecv.echoRequest), icmpRecv.echoRequest.icmpHdr.Seq, spenttime,icmpRecv.ipHdr.TTL);
}
else
{
; //printf("From %s Id_seq %d Destination Host Unreachable ", inet_ntoa(icmpRecv.ipHdr.iaSrc), icmpRecv.echoRequest.icmpHdr.Seq);
}
// sleep(1);
}
nCount ++;
}
close(sockfd);
if (iSuccess >0)
return true;
else
return false;
}
方法(3) 不實現ping功能,更為簡單的方法
//判斷IP地址及埠是否線上
static bool IPLive(QString ip, int port, int timeout = 1000) {
QTcpSocket tcpClient;
tcpClient.abort();
tcpClient.connectToHost(ip, port);
//100毫秒沒有連線上則判斷不線上
return tcpClient.waitForConnected(timeout);
}
//判斷是否通外網
static bool IsWebOk() {
//能接通百度IP說明可以通外網
return IPLive("115.239.211.112", 80);
}
非原創,個人學習筆記,侵權必刪!
參考部落格:https://bbs.csdn.net/topics/391873625
https://www.cnblogs.com/judes/p/7069051.html
相關文章
- C# 實現Ping遠端主機功能C#
- vc實現ping
- Qt加Opencv實現 梯度矯正 功能QTOpenCV梯度
- epoll實現快速ping
- C++ Qt開發:TabWidget實現多窗體功能C++QT
- qt 單獨執行緒實現日誌寫入功能QT執行緒
- Qt中文字編輯器實現語法高亮功能(Qscitinlla)QT
- Qt Android 實現全屏QTAndroid
- Windows7/10實現ICMP(ping命令)Windows
- 在 iOS 平臺實現Ping 和 tracerouteiOS
- windows 2003伺服器 取消ping功能Windows伺服器
- qt實現md5加密QT加密
- Qt右鍵選單實現QT
- QT實現簡單打地鼠QT
- [GXYCTF2019]Ping Ping PingTF2
- Qt實現自定義控制元件QT控制元件
- QT實現組合鍵監測QT
- QT實現簡易串列埠助手QT串列埠
- 簡單介紹VBS 批次Ping的專案實現
- [GXYCTF2019]Ping Ping Ping 1TF2
- QT:用QWebSocket實現webchannel,實現C++與HTML通訊QTWebC++HTML
- Qt 中實現非同步雜湊器QT非同步
- Qt實現系統托盤訊息QT
- mysql實現nextVal功能MySql
- 前端實現水印功能前端
- [GXYCTF2019]Ping Ping Ping 1 - Xxiaoma解題TF2
- 【QT】QtConcurrent::run()+QThreadPool實現多執行緒QTthread執行緒
- Qt實現控制元件的漸隱漸現動效QT控制元件
- centos製作具備telnet和ping功能的docker映象CentOSDocker
- canvas拼圖功能實現Canvas
- 實現微信分享功能
- 第2章 功能實現
- 分頁功能的實現
- servlet實現下載功能Servlet
- 【Vue】考試功能實現Vue
- canvas實現截圖功能Canvas
- socket實現聊天功能(二)
- react 實現插槽slot功能React