欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用Qt實(shí)現(xiàn)控制臺(tái)抓取tcp數(shù)據(jù)包

 更新時(shí)間:2025年11月11日 08:19:57   作者:user5033926650859  
這篇文章主要為大家詳細(xì)介紹了如何使用Qt實(shí)現(xiàn)控制臺(tái)抓取tcp數(shù)據(jù)包,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

前提條件

安裝npcap: 鏈接

項(xiàng)目準(zhǔn)備

創(chuàng)建控制臺(tái)程序

在項(xiàng)目文件中添加包含目錄、附加庫(kù)目錄、附加庫(kù)

INCLUDEPATH += D:/softwares/Libs/NpcapSDK/Include
LIBS += -LD:/softwares/Libs/NpcapSDK/Lib/x64
LIBS += -lwpcap
LIBS += -lole32
LIBS += -lPacket
LIBS += -lIphlpapi

檢查是否已經(jīng)安裝npcap

bool checkNpcapExist()
{
    WCHAR path[512];
    uint len = GetSystemDirectory(path, 480);
    QString systemPath = QString::fromWCharArray(path, len);

    QString npcapFolder = QDir(systemPath).filePath("Npcap");
    return QDir(npcapFolder).exists();
}

也就是判斷目錄: C:\Windows\System32\Npcap 存不存在

獲取網(wǎng)絡(luò)適配器列表

我們需要選擇一個(gè)網(wǎng)絡(luò)適配器去抓取tcp數(shù)據(jù)包,所以需要獲取本地機(jī)器的所有網(wǎng)絡(luò)適配器,當(dāng)然 npcap 提供了 pcap_findalldevs api,但是如果我們要想獲取它的可讀化的 FriendName,需要經(jīng)過(guò)一些操作

QString getDeviceFriendName(const char *devName)
{
    QString friendName(devName);

    // extract guid string by regex
    QRegularExpression regex(R"(({[A-F0-9\-]+}))");
    auto match = regex.match(friendName);

    if (!match.hasMatch()) return friendName;

    // translate guid string to GUID
    GUID guid;

    HRESULT hr = CLSIDFromString(match.captured(1).toStdWString().c_str(), &guid);

    if (!SUCCEEDED(hr)) return friendName;

    // GUID => LUID => Alias(FriendName)
    NET_LUID luid;
    if (0 == ConvertInterfaceGuidToLuid(&guid, &luid))
    {
        WCHAR buffer[256] = {0};
        if (0 == ConvertInterfaceLuidToAlias(&luid, buffer, 256))
        {
            friendName = QString::fromWCharArray(buffer);
        }
    }

    return friendName;
}

int main()
{
    char errbuf[PCAP_ERRBUF_SIZE];
    pcap_if_t *alldevs;
    // pcap_t *handle;

    if (pcap_findalldevs(&alldevs, errbuf) == -1) {
        qCritical() << "Error in pcap_findalldevs:" << errbuf;
        return -1;
    }

    QStringList devNames;
    pcap_if_t *dev = alldevs;
    char* lastName = nullptr;
    while (dev)
    {
        QString devName = getDeviceFriendName(dev->name);
        devNames.append(devName);
        lastName = dev->name;
        dev = dev->next;
    }
    return 0;
}

打開網(wǎng)絡(luò)適配器并設(shè)置篩選條件

一個(gè)網(wǎng)絡(luò)適配器抓到的tcp數(shù)據(jù)包有很多,但是我們只想關(guān)注我們想要的tcp數(shù)據(jù)包,所以需要設(shè)置篩選條件

// open the adapter
pcap_t* adapter = pcap_open_live(lastName, 65536, 1, 1000, errbuf);
if (adapter == nullptr)
{
    pcap_freealldevs(alldevs);
    qDebug() << "fail to open the net adapter: " << lastName;
    return -1;
}

pcap_freealldevs(alldevs);

// set filter
struct bpf_program fcode;
int res = 0;
if ((res = pcap_compile(adapter, &fcode, "tcp port 3000", 1, PCAP_NETMASK_UNKNOWN)) < 0)
{
    qDebug() << "fail to compile:" << pcap_statustostr(res);
    pcap_close(adapter);
    return -1;
}
if ((res = pcap_setfilter(adapter, &fcode) < 0))
{
    qDebug() << "fail to set filter:" << pcap_statustostr(res);
    pcap_close(adapter);
    return -1;
}

這里我們?cè)O(shè)置的條件是只篩選 端口號(hào)3000的tcp數(shù)據(jù)包,篩選字符串為: tcp port 3000

開始抓包,設(shè)置處理函數(shù)

void main()
{
    // start capture loop
    pcap_loop(adapter, 0, packet_handler, nullptr);

    pcap_close(adapter);
}

void packet_handler(u_char* param, const struct pcap_pkthdr* header, const u_char* pkt_data)
{
    Q_UNUSED(param);
    Q_UNUSED(pkt_data);

    uint len = header->len;
    QString str = QString::asprintf("%ld:%ld (%ld)", header->ts.tv_sec, header->ts.tv_usec, len);
    qDebug() << str;
}

運(yùn)行效果

完整代碼

#include <QCoreApplication>
#include <winsock2.h>
#include <QDebug>
#include <windows.h>
#include <QDir>
#include <pcap.h>
#include <QRegularExpression>
#include <objbase.h>
#include <netioapi.h>

bool checkNpcapExist()
{
    WCHAR path[512];
    uint len = GetSystemDirectory(path, 480);
    QString systemPath = QString::fromWCharArray(path, len);

    QString npcapFolder = QDir(systemPath).filePath("Npcap");
    return QDir(npcapFolder).exists();
}

QString getDeviceFriendName(const char *devName)
{
    QString friendName(devName);

    // extract guid string by regex
    QRegularExpression regex(R"(({[A-F0-9\-]+}))");
    auto match = regex.match(friendName);

    if (!match.hasMatch()) return friendName;

    // translate guid string to GUID
    GUID guid;

    HRESULT hr = CLSIDFromString(match.captured(1).toStdWString().c_str(), &guid);

    if (!SUCCEEDED(hr)) return friendName;

    // GUID => LUID => Alias(FriendName)
    NET_LUID luid;
    if (0 == ConvertInterfaceGuidToLuid(&guid, &luid))
    {
        WCHAR buffer[256] = {0};
        if (0 == ConvertInterfaceLuidToAlias(&luid, buffer, 256))
        {
            friendName = QString::fromWCharArray(buffer);
        }
    }

    return friendName;
}

void packet_handler(u_char* param, const struct pcap_pkthdr* header, const u_char* pkt_data)
{
    Q_UNUSED(param);
    Q_UNUSED(pkt_data);

    // struct tm* ltime;
    // char timestr[16];
    // time_t local_tv_sec;

    uint len = header->len;
    QString str = QString::asprintf("%ld:%ld (%ld)", header->ts.tv_sec, header->ts.tv_usec, len);
    qDebug() << str;
}


int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // 判斷npcap是否存在
    if (!checkNpcapExist())
    {
        qDebug() << "Npcap not exists";
        return -1;
    }

    // 檢索網(wǎng)卡列表
    char errbuf[PCAP_ERRBUF_SIZE];
    pcap_if_t *alldevs;
    // pcap_t *handle;

    if (pcap_findalldevs(&alldevs, errbuf) == -1) {
        qCritical() << "Error in pcap_findalldevs:" << errbuf;
        return -1;
    }

    QStringList devNames;
    pcap_if_t *dev = alldevs;
    char* lastName = nullptr;
    while (dev)
    {
        QString devName = getDeviceFriendName(dev->name);
        devNames.append(devName);
        lastName = dev->name;
        dev = dev->next;
    }

    // open the adapter
    pcap_t* adapter = pcap_open_live(lastName, 65536, 1, 1000, errbuf);
    if (adapter == nullptr)
    {
        pcap_freealldevs(alldevs);
        qDebug() << "fail to open the net adapter: " << lastName;
        return -1;
    }

    pcap_freealldevs(alldevs);

    // set filter
    struct bpf_program fcode;
    int res = 0;
    if ((res = pcap_compile(adapter, &fcode, "tcp port 3000", 1, PCAP_NETMASK_UNKNOWN)) < 0)
    {
        qDebug() << "fail to compile:" << pcap_statustostr(res);
        pcap_close(adapter);
        return -1;
    }
    if ((res = pcap_setfilter(adapter, &fcode) < 0))
    {
        qDebug() << "fail to set filter:" << pcap_statustostr(res);
        pcap_close(adapter);
        return -1;
    }

    // start capture loop
    pcap_loop(adapter, 0, packet_handler, nullptr);

    pcap_close(adapter);

    qDebug() << "hello";

    return a.exec();
}

以上就是使用Qt實(shí)現(xiàn)控制臺(tái)抓取tcp數(shù)據(jù)包的詳細(xì)內(nèi)容,更多關(guān)于Qt抓取tcp數(shù)據(jù)包的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 詳解C++設(shè)計(jì)模式編程中對(duì)訪問者模式的運(yùn)用

    詳解C++設(shè)計(jì)模式編程中對(duì)訪問者模式的運(yùn)用

    這篇文章主要介紹了C++設(shè)計(jì)模式編程中對(duì)訪問者模式的運(yùn)用,訪問者模式在不破壞類的前提下為類提供增加新的新操作,需要的朋友可以參考下
    2016-03-03
  • C++映像劫持后門實(shí)例分析

    C++映像劫持后門實(shí)例分析

    這篇文章主要介紹了C++映像劫持后門,實(shí)例分析了C++映像劫持后門的原理與相關(guān)實(shí)現(xiàn)技巧,有助于進(jìn)一步了解后門的原理,需要的朋友可以參考下
    2015-04-04
  • 深入了解C語(yǔ)言冒泡排序優(yōu)解

    深入了解C語(yǔ)言冒泡排序優(yōu)解

    這篇文章主要介紹了C語(yǔ)言冒泡排序法的實(shí)現(xiàn)(升序排序法),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-07-07
  • C語(yǔ)言如何實(shí)現(xiàn)順序表(數(shù)據(jù)結(jié)構(gòu))

    C語(yǔ)言如何實(shí)現(xiàn)順序表(數(shù)據(jù)結(jié)構(gòu))

    這篇文章主要介紹了C語(yǔ)言如何實(shí)現(xiàn)順序表(數(shù)據(jù)結(jié)構(gòu))問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • C++標(biāo)準(zhǔn)模板庫(kù)STL深入講解

    C++標(biāo)準(zhǔn)模板庫(kù)STL深入講解

    STL提供了一組表示容器、迭代器、函數(shù)對(duì)象和算法的模板。容器是一個(gè)與數(shù)組類似的單元,可以存儲(chǔ)若干個(gè)值。STL容器是同質(zhì)的,即存儲(chǔ)的值的類型相同:算法是完成特定任務(wù)(如對(duì)數(shù)組進(jìn)行排序或在鏈表中查找特定值)的處方
    2022-12-12
  • C++面向?qū)ο髮?shí)現(xiàn)萬(wàn)年歷的示例代碼

    C++面向?qū)ο髮?shí)現(xiàn)萬(wàn)年歷的示例代碼

    本文將通過(guò)面向?qū)ο髮?shí)現(xiàn)一個(gè)簡(jiǎn)單的日歷(萬(wàn)年歷)效果,主要會(huì)有以下幾個(gè)模塊:模型、視圖、控制,感興趣的小伙伴可以動(dòng)手嘗試一下
    2022-06-06
  • STL常用算法之排序算法詳解

    STL常用算法之排序算法詳解

    這篇文章主要介紹了STL常用算法之排序算法詳解,STL提供了六大組件,彼此之間可以組合套用,這六大組件分別是:容器、算法、迭代器、仿函數(shù)、適配器、空間配置器,本文主要講算法中的排序算法,需要的朋友可以參考下
    2024-01-01
  • C語(yǔ)言 掃雷程序的實(shí)現(xiàn)

    C語(yǔ)言 掃雷程序的實(shí)現(xiàn)

    這篇文章主要介紹了C語(yǔ)言 掃雷程序的實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • C++中的構(gòu)造函數(shù)詳解

    C++中的構(gòu)造函數(shù)詳解

    這篇文章主要介紹了C++ 中構(gòu)造函數(shù)的實(shí)例詳解的相關(guān)資料,希望通過(guò)本文能幫助到大家,讓大家理解掌握這部分內(nèi)容,需要的朋友可以參考下
    2021-09-09
  • 淺談Qt信號(hào)槽與事件循環(huán)的關(guān)系

    淺談Qt信號(hào)槽與事件循環(huán)的關(guān)系

    本文主要介紹了Qt信號(hào)槽與事件循環(huán)的關(guān)系,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08

最新評(píng)論