m0_53274902 2022-05-15 16:09 采纳率: 0%
浏览 35
已结题

请问link.print(cout):为什么不会将ip地址和包数输出到屏幕

第一个是头文件 IPNodeList.h

#include <fstream>
#include <iostream>
using namespace std;
class IPNode
{
private:
    long m_lIPAddress;                //IP地址
    long m_lCount;                   //发送数据包数
public:
    IPNode*pNext;                   //指向下一个IP节点
    //构造函数
    IPNode(long sourceIP)
    {
        m_lIPAddress = sourceIP;
        m_lCount = 1;                 //初始化数据包个数为1
    }
    //数据包个数加1
    void addCount()
    {
        m_lCount++;
    }
    //返回数据包个数
    long getCount()
    {
        return m_lCount;
    }
    //返回IP地址
    long getIPAddress()
    {
        return m_lIPAddress;
    }
};
//节点链表
class NodeList
{
    IPNode*pHead;                //链表头
    IPNode*pTail;                 //链表尾
public:
    NodeList()
    {
        pHead = pTail = NULL;
    }
    ~NodeList()
    {
 
        if (pHead != NULL)
        {
            IPNode*pTemp = pHead;
            pHead = pHead->pNext;
            delete  pTemp;
        }
    }
    //IP节点加入链表
    void addNode(long sourceIP)
    {
        IPNode* pTemp;
        if (pHead == NULL)             //当链表为空时
        {
            pTail = new IPNode(sourceIP);
            pHead = pTail;
            pTail->pNext = NULL;
        }
        else                      //不为空时
        {
            for (pTemp = pHead; pTemp; pTemp = pTemp->pNext)
            {
                //如果链表中存在此IP,发送数据包个数加1
                if (pTemp->getIPAddress() == sourceIP)
                {
                    pTemp->addCount();
                    break;
                }
            }
            //如果链表中没有此IP,则加入链表
            if (pTemp == NULL)
            {
                pTail->pNext = new IPNode(sourceIP);
                pTail = pTail->pNext;
                pTail->pNext = NULL;
            }
        }
    }
    //输出IP结点,即IP地址和其它发送的IP包个数
    ostream& print(ostream& os)
    {
        for (IPNode*pTemp = pHead; pTemp; pTemp = pTemp->pNext)
        {
            long lTemp = pTemp->getIPAddress();
            os << inet_ntoa(*(in_addr*)&(lTemp)) << '\t';
            os << pTemp->getCount() << endl;
        }
        return os;
    }
};

这是第二个代码main.cpp


#include <iostream>
#include <iomanip>
#include <fstream>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
 
#include "pcap.h"
#include "IPNodeList.h"
//等同于点击“Project→Setting→link"打开object/library modules编辑框后加入lib文件
#pragma comment(lib,"Wpcap.lib")
#pragma comment(lib,"Ws2_32.lib")
 
using namespace std;
//IP包的头部结构
struct ip_header{
    unsigned char ver_ih1;          //版本号(4位)+头部长度(4位)
    unsigned char tos;              //服务类型 
    unsigned short tlen;             //总长度
    unsigned short identification;     //标识
    unsigned short flags_fo;         //标志+片偏移 
    unsigned char tt1;              //生存时间 
    unsigned char proto;            //协议 
    unsigned short crc;             //校检和 
    DWORD saddr;               //源地址
    DWORD daddr;               //目的地址
    unsigned int    op_pad;        //选项+填充
};
 
void main(int argc, char*argv[])
{
    if (argc != 3)          //判断参数是否正确
    {
        cout << "Usage:IPStatistic  time  logfile" << endl;
        cout << "Press any key to continue…" << endl;
        _getch();
        return;
    }
    double sec = atof(argv[1]);
    pcap_if_t *alldevs;    //网络设备结构
    pcap_if_t *d, *head = NULL;
    pcap_t *fp;          //网卡描叙符
    char errbuf[PCAP_ERRBUF_SIZE];     //错误信息
    unsigned int netmask;               //子网掩码
    char packet_filter[] = "ip";            //过滤,选择IP协议
    struct bpf_program fcode;
    struct pcap_pkthdr *header;
    const unsigned char *pkt_data;         //获取网络设备列表
    if (pcap_findalldevs(&alldevs, errbuf) == -1)
    {
        cout << "Error in pcap_findalldevs : " << errbuf;
        return;
    }
    int i = 1;                            //网卡数
    if (i == 0)                           //无设备
    {
        cout << "\nNo interfaces found!Make sure winPacp is installed.\n";
        return;
    }
 
    if (i >= 1)
    {
        int j = 0;
        for (d = alldevs; d; d = d->next)      //列出网卡列表,让用户进行选择
        {
            cout << ++j << ":" << d->name;
            if (d->description)
                cout << " " << d->description << endl;
        }
        cout << "\nEneter the interface number(1 - " << j << ") :";
        int k;
        cin >> k;
 
        if (k<1 || k>j)
        {
            cout << "out of range" << endl;
            return;
        }
        for (d = alldevs, i = 1; i<k; d = d->next, i++);   //找到选择的网卡
        head = d;
    }
 
    //以混杂模式打开网卡
    if ((fp = pcap_open_live(head->name, 1000, 1, 1000, errbuf)) == NULL)
    {
        cout << "\nUnable to open the adapter." << endl;
        pcap_freealldevs(alldevs);
        return;
    }
 
    //获得子网掩码
    if (head->addresses != NULL)
        netmask = ((sockaddr_in*)(head->addresses->netmask))->sin_addr.S_un.S_addr;
    else
        //没有地址假设为C类地址
        netmask = 0xffffff;
 
    //编译过滤器
    if (pcap_compile(fp, &fcode, packet_filter, i, netmask)<0)
    {
        cout << "\nUnable to compile the packet filter.Check the syntax.\n";
        pcap_freealldevs(alldevs);
        return;
    }
 
    //设置过滤器
    if (pcap_setfilter(fp, &fcode)<0)
    {
        cout << "\nEeeor setting the filter.\n";
        pcap_freealldevs(alldevs);
        return;
    }
 
    //显示提示信息及每项含义
    cout << "\t\tlistening on " << head->description << " " << endl << endl;
    ofstream fout(argv[2], ios::app);        //日志记录文件
    fout << "\tIP Statistic : (" << sec << "minutes)" << endl;
    time_t tmp = time(NULL);
    fout << ctime(&tmp);
    cout << "IP Statistic : (" << sec << "Seconds)" << endl;
    fout << "   Sour IP     " << "\tpacket numbers" << endl;
    //释放设备列表
    pcap_freealldevs(alldevs);
    NodeList link;           //存储数据用链表
    int res;
    time_t beg;
    time_t end;
    time(&beg);            //获得当前时间
    while ((res = pcap_next_ex(fp, &header, &pkt_data)) >= 0)
    {
        time(&end);         //获得系统时间
        if (end - beg >= sec)  //计算系统时间
            break;
        if (res == 0)
        continue;        //超时
        ip_header*ih;
        //找到IP头位置
        ih = (ip_header*)(pkt_data + 14);   //14为以太头的长度
        link.addNode(ih->saddr);       //将源IP地址假如链表
    }
    cout << "Sour IP   " << '\t' << "packet numbers" << endl;
    link.print(cout);          //输出到屏幕
    link.print(fout);          //输出到日志文件
    fout << endl;
}

参考https://blog.csdn.net/st_kalecgos/article/details/23383009?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165258757616782388084877%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=165258757616782388084877&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-4-23383009-null-null.142^v9^pc_search_result_cache,157^v4^control&utm_term=winpcap%E7%9B%91%E6%8E%A7ip%E6%95%B0%E6%8D%AE%E5%8C%85%E6%B5%81%E9%87%8F&spm=1018.2226.3001.4187

问题在最后link.print(cout):为什么不会将ip地址和包数输出到屏幕

  • 写回答

2条回答 默认 最新

  • 赵4老师 2022-05-16 11:25
    关注

    计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……

    对学习编程者的忠告:

    img

    多用小脑和手,少用大脑、眼睛和嘴,会更快地学会编程!
    眼过千遍不如手过一遍!
    书看千行不如手敲一行!
    手敲千行不如单步一行!
    单步源代码千行不如单步Debug版对应汇编一行!
    单步Debug版对应汇编千行不如单步Release版对应汇编一行!
    不会单步Release版对应汇编?在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有,然后在IDE中运行。(一般人我不告诉他!

    img

    单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后,就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。

    VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
    对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。

    评论

报告相同问题?

问题事件

  • 系统已结题 5月23日
  • 修改了问题 5月15日
  • 修改了问题 5月15日
  • 创建了问题 5月15日

悬赏问题

  • ¥15 更换了一个新的win10系统,再下载VS时碰到的问题,是C++组件的?
  • ¥15 关于罗技鼠标宏lua文件的问题
  • ¥15 halcon ocr mlp 识别问题
  • ¥15 已知曲线满足正余弦函数,根据其峰值,还原出整条曲线
  • ¥20 无法创建新的堆栈防护界面
  • ¥15 sessionStorage在vue中的用法
  • ¥15 wordpress更换域名后用户图片头像不显示
  • ¥15 如何在ubunto上安装CEF (Chromium Embedded Framework),并且基于qt实现打开一个web
  • ¥30 AD9854 为什么输出波形幅度受限,AI机器人勿扰
  • ¥15 如何在ubunto上安装CEF (Chromium Embedded Framework