start(orderInfo)_qt ping">
当前位置:   article > 正文

QT实现ping功能_qt ping

qt ping

QT实现ping功能

1.问题描述:

  • 界面点击“建立连接”按钮实现测试主机和目的主机的通信链路是否正常。

2.解决思路:

  • "建立连接"按钮响应槽函数,槽函数实现ping操作,返回ping通的结果。

3.解决方法:

方法(1) QProcess调用命令行,读取标准输出即可。

QProcess pingProcess;
QString strArg = "ping " + strPingIP + " -n 1 -i 2";  //strPingIP 为设备IP地址
pingProcess.start(strArg,QIODevice::ReadOnly);
pingProcess.waitForFinished(-1);

QString p_stdout = QString::fromLocal8Bit( pingProcess.readAllStandardOutput());

qDebug()<<p_stdout ;
bool bPingSuccess = false;

if(p_stdout.contains("TTL=")) //我采用这个字符来判断 对不对?
{ 
	bPingSuccess = true;
}else
{ 
	bPingSuccess = false;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

方法二(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;
 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130

方法(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);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

非原创,侵权必删!
参考文章:https://bbs.csdn.net/topics/391873625
https://www.cnblogs.com/judes/p/7069051.html
http://www.voidcn.com/article/p-cbvxdzwt-bny.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/203966
推荐阅读
相关标签
  

闽ICP备14008679号