广联达钢筋 捕捉不到点:WinPcap基础知识(第四课:不用回调函数来捕捉数据包)
来源:百度文库 编辑:偶看新闻 时间:2024/04/28 18:25:27
这节课程中的例子程序完成的功能和上节课的一样,但是使用的是pcap_next_ex()而不是pcap_loop().
基于回调捕获机制的 pcap_loop()是非常优雅的,在很多情况下都是一个不错的选择。不过,有时候处理一个回调函数显得不太现实 --- 通常这会使程序更加复杂,在使用多线程或者c++类的时候尤其如此。
在这种情况下,可以直接调用 pcap_next_ex() 来返回一个数据包 -- 这样程序员可以在仅仅想使用它们的时候再处理 pcap_next_ex() 返回的数据包。
这个函数的参数和回调函数 pcap_loop() 的一样 -- 由一个网络适配器描述符作为入口参数和两个指针作为出口参数,这两个指针将在函数中被初始化,然后再返回给用户(一个指向pcap_pkthdr 结构,另一个指向一个用作数据缓冲区的内存区域)。
在下面的程序中,我们继续使用上一节课中的例子的数据处理部分的代码,把这些代码拷贝到main()函数中pcap_next_ex()的后面。view plaincopy to clipboardprint?
#define HAVE_REMOTE
#include
#pragma comment(lib,"wpcap.lib")
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;
u_char *pkt_data;
/* Retrieve the device list on the local machine */
if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1)
{
fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
exit(1);
}
/* Print the list */
for(d=alldevs; d; d=d->next)
{
printf("%d. %s", ++i, d->name);
if (d->description)
printf(" (%s)\n", d->description);
else
printf(" (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");
/* Free the device list */
pcap_freealldevs(alldevs);
return -1;
}
/* Jump to the selected adapter */
for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
/* Open the device */
if ( (adhandle= pcap_open(d->name, // name of the device
65536, // portion of the packet to capture.
// 65536 guarantees that the whole packet will be captured on all the link layers
PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode
1000, // read timeout
NULL, // authentication on the remote machine
errbuf // error buffer
) ) == NULL)
{
fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
/* Free the device list */
pcap_freealldevs(alldevs);
return -1;
}
printf("\nlistening on %s...\n", d->description);
/* At this point, we don't need any more the device list. Free it */
pcap_freealldevs(alldevs);
/* Retrieve the packets */
while((res = pcap_next_ex( adhandle, &header, (const u_char**)&pkt_data)) >= 0){
if(res == 0)
/* Timeout elapsed */
continue;
/* convert the timestamp to readable format */
ltime=localtime(&header->ts.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;
}
#define HAVE_REMOTE
#include#pragma comment(lib,"wpcap.lib")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;
u_char *pkt_data;
/* Retrieve the device list on the local machine */
if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1)
{
fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
exit(1);
}
/* Print the list */
for(d=alldevs; d; d=d->next)
{
printf("%d. %s", ++i, d->name);
if (d->description)
printf(" (%s)\n", d->description);
else
printf(" (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");
/* Free the device list */
pcap_freealldevs(alldevs);
return -1;
}
/* Jump to the selected adapter */
for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
/* Open the device */
if ( (adhandle= pcap_open(d->name, // name of the device
65536, // portion of the packet to capture.
// 65536 guarantees that the whole packet will be captured on all the link layers
PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode
1000, // read timeout
NULL, // authentication on the remote machine
errbuf // error buffer
) ) == NULL)
{
fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
/* Free the device list */
pcap_freealldevs(alldevs);
return -1;
}
printf("\nlistening on %s...\n", d->description);
/* At this point, we don't need any more the device list. Free it */
pcap_freealldevs(alldevs);
/* Retrieve the packets */
while((res = pcap_next_ex( adhandle, &header, (const u_char**)&pkt_data)) >= 0){
if(res == 0)
/* Timeout elapsed */
continue;
/* convert the timestamp to readable format */
ltime=localtime(&header->ts.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_next_ex()方法,文档里面没有介绍是阻塞得还是非阻塞,个人认为是阻塞得,也就是说从开始执行,一直倒接收倒一个包才返回。尽管这里是阻塞得,但是设置一个变量每次检查一下,看看是否是用户要求关闭接收,这个操作还是没什么问题。不会出现虽然用户设置了停止阻塞得标志位,但是由于此方法是阻塞的,因为等不到数据包而一直没有响应用户,因为这里有一个事实大家应该明白,网上发送的数据包时时刻刻都在。
注意:之所以要使用pcap_next_ex()而不使用pcap_next()是因为pcap_next()有些非常讨厌的限制。首先,他不是很有效的方法,因为它隐藏了回调方法,但是还是依靠pcap_dispatch()。第二,它不能探测出EOF,所以在合并文件时它几乎没用。 另外,pcap_next_ex()方法的返回值可以给用户很多的提示,对应的所有可能情况。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/qsycn/archive/2009/08/18/4458383.aspx
基于回调捕获机制的 pcap_loop()是非常优雅的,在很多情况下都是一个不错的选择。不过,有时候处理一个回调函数显得不太现实 --- 通常这会使程序更加复杂,在使用多线程或者c++类的时候尤其如此。
在这种情况下,可以直接调用 pcap_next_ex() 来返回一个数据包 -- 这样程序员可以在仅仅想使用它们的时候再处理 pcap_next_ex() 返回的数据包。
这个函数的参数和回调函数 pcap_loop() 的一样 -- 由一个网络适配器描述符作为入口参数和两个指针作为出口参数,这两个指针将在函数中被初始化,然后再返回给用户(一个指向pcap_pkthdr 结构,另一个指向一个用作数据缓冲区的内存区域)。
在下面的程序中,我们继续使用上一节课中的例子的数据处理部分的代码,把这些代码拷贝到main()函数中pcap_next_ex()的后面。view plaincopy to clipboardprint?
#define HAVE_REMOTE
#include
#pragma comment(lib,"wpcap.lib")
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;
u_char *pkt_data;
/* Retrieve the device list on the local machine */
if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1)
{
fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
exit(1);
}
/* Print the list */
for(d=alldevs; d; d=d->next)
{
printf("%d. %s", ++i, d->name);
if (d->description)
printf(" (%s)\n", d->description);
else
printf(" (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");
/* Free the device list */
pcap_freealldevs(alldevs);
return -1;
}
/* Jump to the selected adapter */
for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
/* Open the device */
if ( (adhandle= pcap_open(d->name, // name of the device
65536, // portion of the packet to capture.
// 65536 guarantees that the whole packet will be captured on all the link layers
PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode
1000, // read timeout
NULL, // authentication on the remote machine
errbuf // error buffer
) ) == NULL)
{
fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
/* Free the device list */
pcap_freealldevs(alldevs);
return -1;
}
printf("\nlistening on %s...\n", d->description);
/* At this point, we don't need any more the device list. Free it */
pcap_freealldevs(alldevs);
/* Retrieve the packets */
while((res = pcap_next_ex( adhandle, &header, (const u_char**)&pkt_data)) >= 0){
if(res == 0)
/* Timeout elapsed */
continue;
/* convert the timestamp to readable format */
ltime=localtime(&header->ts.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;
}
#define HAVE_REMOTE
#include
{
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;
u_char *pkt_data;
/* Retrieve the device list on the local machine */
if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1)
{
fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
exit(1);
}
/* Print the list */
for(d=alldevs; d; d=d->next)
{
printf("%d. %s", ++i, d->name);
if (d->description)
printf(" (%s)\n", d->description);
else
printf(" (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");
/* Free the device list */
pcap_freealldevs(alldevs);
return -1;
}
/* Jump to the selected adapter */
for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
/* Open the device */
if ( (adhandle= pcap_open(d->name, // name of the device
65536, // portion of the packet to capture.
// 65536 guarantees that the whole packet will be captured on all the link layers
PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode
1000, // read timeout
NULL, // authentication on the remote machine
errbuf // error buffer
) ) == NULL)
{
fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
/* Free the device list */
pcap_freealldevs(alldevs);
return -1;
}
printf("\nlistening on %s...\n", d->description);
/* At this point, we don't need any more the device list. Free it */
pcap_freealldevs(alldevs);
/* Retrieve the packets */
while((res = pcap_next_ex( adhandle, &header, (const u_char**)&pkt_data)) >= 0){
if(res == 0)
/* Timeout elapsed */
continue;
/* convert the timestamp to readable format */
ltime=localtime(&header->ts.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_next_ex()方法,文档里面没有介绍是阻塞得还是非阻塞,个人认为是阻塞得,也就是说从开始执行,一直倒接收倒一个包才返回。尽管这里是阻塞得,但是设置一个变量每次检查一下,看看是否是用户要求关闭接收,这个操作还是没什么问题。不会出现虽然用户设置了停止阻塞得标志位,但是由于此方法是阻塞的,因为等不到数据包而一直没有响应用户,因为这里有一个事实大家应该明白,网上发送的数据包时时刻刻都在。
注意:之所以要使用pcap_next_ex()而不使用pcap_next()是因为pcap_next()有些非常讨厌的限制。首先,他不是很有效的方法,因为它隐藏了回调方法,但是还是依靠pcap_dispatch()。第二,它不能探测出EOF,所以在合并文件时它几乎没用。 另外,pcap_next_ex()方法的返回值可以给用户很多的提示,对应的所有可能情况。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/qsycn/archive/2009/08/18/4458383.aspx
什么是WinPcap?
WinPcap是什么?
基础知识
基础知识
基础知识
基础知识
报关员考试大纲第四章报关基础知识,教材中没有答案,应该怎么复习,谢谢
winpcap安装失败
winpcap是什么软件?
winpcap 3.0是什么
winpcap不能安装成功
请问WinPcap是什么东西?
西游记第四十三回
水浒传第四回赏析
C:\Program Files\WinPcap,winpcap是什么?
WinPcap是什么?干什么用的?
winpcap(windows packet capture) 能删吗?
winpcap(windows packet capture) 能删吗?
winpcap 3.1的安装问题
三国演义第四回内容梗概
《三国演义》第四十三回简介
篮球比赛中,第二 第三 第四节的开始用不用跳球
如何在vb中使用winpcap
请问在deiphi可以使用winpcap吗??