这里使用pcap_next_ex()函数代替pcap_loop()函数来实现捕获数据包。pcap_loop()函数基于回调原理实现数据捕获,这是一种精妙的方法,并且在某些场合中,它是一种很好的选择。 然而,处理回调有时候并不实用 -- 它会增加程序的复杂度,特别是在拥有多线程的C++程序中。

也可以通过直接调用pcap_next_ex()方法来捕获数据包,当只有显示调用时才能捕获数据包。

下面是pcap_next_ex()函数的具体格式:

int pcap_next_ex  ( pcap_t *  p,  struct pcap_pkthdr **  pkt_header,  const u_char **  pkt_data   ); 

各个参数含义如下:

p:pcap句柄;

pkt_header:指向一个pcap_pkthdr结构的指针,用于保存捕获数据包的基本信息;

pkt_data:保存捕获的数据;

函数的功能是捕获一个数据包,然后用捕获的数据包填充pkt_header和pkt_data参数,根据结果不同,返回不同的数字。返回结果如下:

  • 1:捕获数据成功;
  • 0:数据捕获超时;
  • -1:发生错误;
  • -2:到达离线文件的结尾;
下面的代码使用pcap_next_ex()函数捕获数据包:
#include "pcap.h"int main()
{pcap_if_t *alldevs;pcap_if_t *d;int inum;int i = 0;pcap_t *adhandle;int res;char errbuf[PCAP_ERRBUF_SIZE];struct tm *ltime;char timestr[16];struct pcap_pkthdr *header;const u_char *pkt_data;time_t local_tv_sec;/* 获取本机设备列表 */if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1){fprintf(stderr, "Error in pcap_findalldevs: %s\n", errbuf);exit(1);}/* 打印列表 */for (d = alldevs; d; d = d->next){printf("%d. %s", ++i, d->name);if (d->description)printf(" (%s)\n", d->description);elseprintf(" (No description available)\n");}if (i == 0){printf("\nNo interfaces found! Make sure WinPcap is installed.\n");return -1;}printf("Enter the interface number (1-%d):", i);scanf("%d", &inum);if (inum < 1 || inum > i){printf("\nInterface number out of range.\n");/* 释放设备列表 */pcap_freealldevs(alldevs);return -1;}/* 跳转到已选中的适配器 */for (d = alldevs, i = 0; i< inum - 1;d = d->next, i++);/* 打开设备 */if ((adhandle = pcap_open(d->name,          // 设备名65536,            // 要捕捉的数据包的部分 // 65535保证能捕获到不同数据链路层上的每个数据包的全部内容PCAP_OPENFLAG_PROMISCUOUS,    // 混杂模式1000,             // 读取超时时间NULL,             // 远程机器验证errbuf            // 错误缓冲池)) == NULL){fprintf(stderr, "\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);/* 释放设列表 */pcap_freealldevs(alldevs);return -1;}printf("\nlistening on %s...\n", d->description);/* 释放设备列表 */pcap_freealldevs(alldevs);/* 获取数据包 */while ((res = pcap_next_ex(adhandle, &header, &pkt_data)) >= 0) {if (res == 0)/* 超时时间到 */continue;/* 将时间戳转换成可识别的格式 */local_tv_sec = header->ts.tv_sec;ltime = localtime(&local_tv_sec);strftime(timestr, sizeof timestr, "%H:%M:%S", ltime);printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len);}if (res == -1) {printf("Error reading the packets: %s\n", pcap_geterr(adhandle));return -1;}return 0;
}
其中,pcap_geterr()函数得到最后一次调用错误。
结果如下:

WinPcap笔记(5):不用回调方法捕获数据包相关推荐

  1. 不用回调方法捕获数据包

    这次将用 pcap_next_ex() 函数代替上一次的 pcap_loop()函数. pcap_loop()函数是基于回调的原理来进行数据捕获,这是一种精妙的方法,并且在某些场合中,它是一种很好的选 ...

  2. winPcap编程之打开适配器并捕获数据包(四 转)

    在贴源码之前先介绍一个将要用到的很重要的函数--pcap_open(),下面是pcap_open()在remote-ex.h中的声明: pcap_t *pcap_open(const char *so ...

  3. WinPcap笔记(9):保存数据包到堆文件

    这里我们将捕获到的数据包保存到堆文件里.堆文件的格式是libpcap的一种.这种格式中,包含了被捕捉到的包的二进制数据,并且,这种格式是许多网络工具所使用的一种标准,这些工具包括WinDump,Eth ...

  4. WinPcap笔记(7):分析数据包(1)

    现在,我们可以捕获并过滤网络流量了,那就简单协议个程序分析网络数据包. 这里我们只是解析所捕获数据包的首部,打印一些数据包首部的信息.我们以UDP为例,因为UDP比较简单. 首先,应该介绍下网络数据包 ...

  5. WinPcap笔记(8):分析数据包(2)

    上一讲里分析了UDP数据包,这里简单分析一下TCP数据包. TCP是面向有连接的传输协议,因此相对来说比较复杂.下面是TCP报头的格式: 同样,需要我们自己定义TCP报头: /* tcp 首部 */ ...

  6. WinPcap笔记(6):过滤数据包

    wpcap的过滤器是以已声明的谓词语法为基础的.过滤器是一个ASCII字符串,它包含了一个过滤表达式.pcap_compile()把这个表达式编译成内核级的包过滤器. 这个表达式会选择哪些数据包将会被 ...

  7. WinPcap笔记(4):打开适配器并捕获数据包

    前面已经能够得到是设备的信息了,现在开始做真正有意义的事情:打开适配器并捕获数据包.这里将用到函数pcap_open(),下面是函数的具体格式: pcap_t* pcap_open ( const c ...

  8. 利用WinPcap技术捕获数据包

    前言  随着网络入侵的不断发展,网络安全变得越来越重要,于是网络入侵取证系统的研究也变得日益重要.在网络入侵取证系统中,对网络上传送的数据包进行有效的监听即捕获包是目前取证的关键技术,只有进行高效的数 ...

  9. WinPcap学习(四)打开适配器并捕获数据包

    打开设备的函数是pcap_open().下面参数snaplen,flags和to_ms的解释说明 snaplen制定要捕获数据包中的哪些部分.在一些操作系统中(比如xBSD和Win32),驱动可以被配 ...

最新文章

  1. 开发者都想收藏的深度学习脑图,我们抢先曝光了!
  2. java类加载 复制_Java 类加载全过程
  3. Java NIO系列教程(一) Java NIO 概述
  4. 三刺激值计算公式_常用的车削、铣削、钻削加工计算公式全在这里了,随用随查...
  5. Freemarker + xml 实现Java导出word
  6. 网站优化之关键词的挖掘准则有哪些?
  7. addeventlistener事件第三个参数_简析JavaScript 事件绑定、事件冒泡、事件捕获和事件执行顺序...
  8. endnote中科大版区别_研究生科研入门Endnote文献管理软件使用
  9. impacket安装 python_Impacket网络协议工具包介绍
  10. mongodb mysql json数据_使用MongoDB与MySQL有很多JSON字段?
  11. 将你的数据导入到json格式
  12. 如何判断 msn 是否在线 [根据msn是否在线动态显示 msn 头像]
  13. 抓取scrapy中文文档(我的第一个爬虫)
  14. 教你炒股票25:吻,MACD、背弛、中枢
  15. java实现12306查票_java爬取12306查询余票的操作
  16. Linux—虚拟机下如何查看系统是多少位的?32 or 64
  17. 【六类网线的制作方法】
  18. 怎么去除视频字幕清理视频字幕或水印的四种方法
  19. 三星S95Z / S90Z OLED 电视 评测
  20. 西红柿助手的安装使用及其设置(Visual Assist X)

热门文章

  1. 将 JAR 转为 EXE – JSMOOTH 的使用教程(第二期)(转载)
  2. 大话设计模式之设计模式遵循的七大原则
  3. matlab数据游标不能使用,启用数据游标模式
  4. java图形界面的监听_非专业码农 JAVA学习笔记 用户图形界面设计与实现-所有控件的监听事件...
  5. 服务器微信了早上好,每天早上好的问候语 微信早安问候语合集66句
  6. linux内存分配堆栈数据段代码段,linux – LD_PRELOAD堆栈和数据段内存分配
  7. Finally语句块的执行
  8. 【C++ grammar】引用
  9. android jni示例_Android服务示例
  10. Java类class forName()方法及示例