Qt WinAPI - Lesson 007. Working with ICMP Ping in Qt


Immediately I want to upset you, dear readers. Qt does not have the functionality to work with the ICMP protocol and therefore have to use for this purpose API target operating system. However, this is not surprising. The ICMP protocol is a low-level protocol, and to work with it requires the use of raw sockets, which are not implemented in Qt.

But this is not a particular problem, because the main target platform has the necessary API to implement ping packages. For example Microsoft provides the simple use of ICMP protocol based IcmpSendEcho function.


The IcmpSendEcho function sends an IPv4 ICMP echo request and returns any echo response replies. The call returns when the time-out has expired or the reply buffer is filled.

DWORD IcmpSendEcho(
  _In_     HANDLE                 IcmpHandle,
  _In_     IPAddr                 DestinationAddress,
  _In_     LPVOID                 RequestData,
  _In_     WORD                   RequestSize,
  _In_opt_ PIP_OPTION_INFORMATION RequestOptions,
  _Out_    LPVOID                 ReplyBuffer,
  _In_     DWORD                  ReplySize,
  _In_     DWORD                  Timeout


IcmpHandle [in]
The open handle returned by the IcmpCreateFile function.

DestinationAddress [in]
The IPv4 destination address of the echo request, in the form of an IPAddr structure.

RequestData [in]
A pointer to a buffer that contains data to send in the request.

RequestSize [in]
The size, in bytes, of the request data buffer pointed to by the RequestData parameter.

RequestOptions [in, optional]
A pointer to the IP header options for the request, in the form of an IP_OPTION_INFORMATION structure. On a 64-bit platform, this parameter is in the form for an IP_OPTION_INFORMATION32 structure.

This parameter may be NULL if no IP header options need to be specified.

ReplyBuffer [out]
A buffer to hold any replies to the echo request. Upon return, the buffer contains an array of ICMP_ECHO_REPLY structures followed by the options and data for the replies. The buffer should be large enough to hold at least one ICMP_ECHO_REPLY structure plus RequestSize bytes of data.

On a 64-bit platform, upon return the buffer contains an array of ICMP_ECHO_REPLY32 structures followed by the options and data for the replies.

ReplySize [in]
The allocated size, in bytes, of the reply buffer. The buffer should be large enough to hold at least one ICMP_ECHO_REPLY structure plus RequestSize bytes of data. On a 64-bit platform, The buffer should be large enough to hold at least one ICMP_ECHO_REPLY32 structure plus RequestSize bytes of data.

This buffer should also be large enough to also hold 8 more bytes of data (the size of an ICMP error message).

Timeout [in]
The time, in milliseconds, to wait for replies.

Return value

The IcmpSendEcho function returns the number of ICMP_ECHO_REPLY or ICMP_ECHO_REPLY32 structures stored in the ReplyBuffer . The status of each reply is contained in the structure. If the return value is zero, call GetLastError for additional error information.

If the function fails, the extended error code returned by GetLastError can be one of the following values.

  • ERROR_INSUFFICIENT_BUFFER - The data area passed to a system call is too small. This error is returned if the ReplySize parameter indicates that the buffer pointed to by the ReplyBuffer parameter is too small.
  • ERROR_INVALID_PARAMETER - An invalid parameter was passed to the function. This error is returned if the IcmpHandle parameter contains an invalid handle. This error can also be returned if the ReplySize parameter specifies a value less than the size of an ICMP_ECHO_REPLY or ICMP_ECHO_REPLY32 structure.
  • ERROR_NOT_ENOUGH_MEMORY - Not enough memory is available to complete the operation.
  • ERROR_NOT_SUPPORT - The request is not supported. This error is returned if no IPv4 stack is on the local computer.
  • IP_BUF_TOO_SMALL - The size of the ReplyBuffer specified in the ReplySize parameter was too small.
  • Other - Use FormatMessage to obtain the message string for the returned error.

Work with ICMP

IcmpSendEcho function sends an ICMP echo request to the specified address and returns the number of received and saved responses ReplyBuffer . IcmpSendEcho function is a synchronous function and returns the value after the end of the waiting time for an answer. If zero is returned, to obtain extended information call the GetLastError function.

In order to use this part of WinAPI, you must register the following two lines to the .Pro project file:

LIBS     += -lws2_32
LIBS     += -liphlpapi

And also connect the following libraries:

#include "winsock2.h"
#include "iphlpapi.h"
#include "icmpapi.h"

The main application window

In order to become familiar with the ICMP protocol will create a window with the following interface will be displayed where a response to requests, the IP-address and the start button.


Apart from the key slot ads you are not able to see anything interesting, but nevertheless bring a header file.

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QDebug>

namespace Ui {
class Widget;

class Widget : public QWidget

    explicit Widget(QWidget *parent = 0);

private slots:
    void on_pushButton_clicked();

    Ui::Widget *ui;

#endif // WIDGET_H


And here the most interesting. At the touch of a button We will ping the selected contact IP-address. For beauty solutions I introduced validation of IP-addresses in lineEdit field.

#include "widget.h"
#include "ui_widget.h"
#include "winsock2.h"
#include "iphlpapi.h"
#include "icmpapi.h"

Widget::Widget(QWidget *parent) :
    ui(new Ui::Widget)

    // We validate the input data IP-addresses
    QString ipRange = "(?:[0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])";

    QRegExp ipRegex ("^" + ipRange
                     + "\\." + ipRange
                     + "\\." + ipRange
                     + "\\." + ipRange + "$");

    QRegExpValidator *ipValidator = new QRegExpValidator(ipRegex, this);

    delete ui;

void Widget::on_pushButton_clicked()
    // We declare variables
    HANDLE hIcmpFile;                       // Handler
    unsigned long ipaddr = INADDR_NONE;     // Destination address
    DWORD dwRetVal = 0;                     // Number of replies
    char SendData[32] = "Data Buffer";      // The buffer data being sent
    LPVOID ReplyBuffer = NULL;              // buffer replies
    DWORD ReplySize = 0;                    // Buffer Size responses

    // Set the IP-address of the field qlineEdit
    ipaddr = inet_addr(ui->lineEdit->text().toStdString().c_str());
    hIcmpFile = IcmpCreateFile();   // create a handler

    // Select the buffer memory responses
    ReplySize = sizeof(ICMP_ECHO_REPLY) + sizeof(SendData);
    ReplyBuffer = (VOID*) malloc(ReplySize);

    // Call the ICMP echo request function
    dwRetVal = IcmpSendEcho(hIcmpFile, ipaddr, SendData, sizeof(SendData),
                NULL, ReplyBuffer, ReplySize, 1000);

    // We create a row in which we write the response message
    QString strMessage = "";

    if (dwRetVal != 0) {
        // The structure of the echo response
        PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)ReplyBuffer;
        struct in_addr ReplyAddr;
        ReplyAddr.S_un.S_addr = pEchoReply->Address;

        strMessage += "Sent icmp message to " + ui->lineEdit->text() + "\n";
        if (dwRetVal > 1) {
            strMessage += "Received " + QString::number(dwRetVal) + " icmp message responses \n";
            strMessage += "Information from the first response: ";
        else {
            strMessage += "Received " + QString::number(dwRetVal) + " icmp message response \n";
            strMessage += "Information from the first response: ";
            strMessage += "Received from ";
            strMessage += inet_ntoa( ReplyAddr );
            strMessage += "\n";
            strMessage += "Status = " + pEchoReply->Status;
            strMessage += "Roundtrip time = " + QString::number(pEchoReply->RoundTripTime) + " milliseconds \n";
    } else {
        strMessage += "Call to IcmpSendEcho failed.\n";
        strMessage += "IcmpSendEcho returned error: ";
        strMessage += QString::number(GetLastError());

    ui->textEdit->setText(strMessage); // Display information about the received data
    free(ReplyBuffer); // frees memory


As a result, you should have an application that will ping the selected IP-address.


We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.
Support the author Donate


Only authorized users can post comments.
Please, Log in or Sign up

Hello, Dear Users of EVILEG!!!

If the site helped you, then support the development of the site financially, please.

You can do it by following ways:

Thank you, Evgenii Legotckoi

April 1, 2020, 8:03 a.m.
Dmitry Kozhinov

C++ - Test 001. The first program and data types

  • Result:40points,
  • Rating points-8
March 30, 2020, 12:47 p.m.

C++ - Test 001. The first program and data types

  • Result:60points,
  • Rating points-1
March 29, 2020, 12:14 p.m.

C++ - Тест 003. Условия и циклы

  • Result:71points,
  • Rating points1
Last comments
April 3, 2020, 8:06 a.m.
Konstantin Grudnitskiy

Я надеюсь вы уже разобрались в чем дело, но если вдруг нет, то проблема состоит в том, что вы пытаетесь запустить программу из интерпретатора питона. Файл main.py это уже готова…
April 3, 2020, 6:18 a.m.
Konstantin Grudnitskiy

>>> text = 'hello world'>>> ' '.join(word for word in text.split()[:-1])'hello'>>> def remove_last_word(text):... return text and ' '.join(word for word in text.s…
March 27, 2020, 2:40 p.m.
Evgenij Legotskoj

Добрый день. В конце пятой статьи скачать можете.
March 27, 2020, 2:28 p.m.
mkdir _

Здравствуйте, а можно, пожалуйста, ссылку на целые исходники, если есть?
March 27, 2020, 4:36 a.m.
Evgenij Legotskoj

Скорее всего также, как и для установки всех остальных переменых в CMake, через использование set
Now discuss on the forum
April 5, 2020, 5:09 a.m.

Попробуйте CQtDeployer или windeployqt.
April 5, 2020, 2:35 a.m.

Так работает console.log(textEmail.text) var str = textEmail.text; var n = str.search(/^((([0-9A-Za-z]{1}[-0-9A-z\.]{1,}[0-9A-Za-z]{1})|([0-9А-Яа-я]{1}[-0-9А-я\.]{1,}[…
April 3, 2020, 12:53 p.m.

Само собою на компе этого незаметно.
April 3, 2020, 8:48 a.m.

Евгений, добрый день. Спасибо!
April 3, 2020, 7:52 a.m.

да вроде много чего установленно, если неправильный путь указать то же самое, пробовал запустить видео через плей лист (по примерам из док)и из него назад путь взять, не получилось
© EVILEG 2015-2019
Recommend hosting TIMEWEB