C++ 线程和pcap问题
我有一个GUI程序,允许用户扫描网络,问题是当调用pcap_循环函数时,我的GUI程序没有响应(pcap_循环阻塞当前线程) 当我尝试使用pthreads时,我在pcap_循环函数中遇到了一个SIGSEGV错误。为什么?这就好像线程看不到procPacket函数本身一样C++ 线程和pcap问题,c++,pcap,libpcap,C++,Pcap,Libpcap,我有一个GUI程序,允许用户扫描网络,问题是当调用pcap_循环函数时,我的GUI程序没有响应(pcap_循环阻塞当前线程) 当我尝试使用pthreads时,我在pcap_循环函数中遇到了一个SIGSEGV错误。为什么?这就好像线程看不到procPacket函数本身一样 void procPacket(u_char *arg, const struct pcap_pkthdr *pkthdr, const u_char *packet) { //show packets here } v
void procPacket(u_char *arg, const struct pcap_pkthdr *pkthdr, const u_char *packet)
{
//show packets here
}
void* pcapLooper(void* param)
{
pcap_t* handler = (pcap_t*) param;
pcap_loop(handler, 900 ,procPacket, NULL );
}
//some function that runs when a button is pressed
//handler has been opened through pcap_open_live
pthread_t scanner;
int t = pthread_create(&scanner,NULL,&pcapLooper, &handler );
if(t)
{
std::cout << "failed" << std::endl;
}
pthread_join(scanner,NULL);
//do other stuff.
void procPacket(u_char*arg,const struct pcap_pkthdr*pkthdr,const u_char*packet)
{
//在这里显示数据包
}
void*pcapLooper(void*param)
{
pcap_t*处理程序=(pcap_t*)参数;
pcap_循环(处理程序,900,程序包,空);
}
//当按下按钮时运行的一些功能
//已通过pcap\u open\u live打开处理程序
pthread_t扫描器;
int t=pthread_create(&scanner,NULL,&pcapLooper,&handler);
if(t)
{
std::cout您需要的“和”要少得多。假设
pcap_t *handle = pcap_open_live(...);
你需要的“和”要少得多
pcap_t *handle = pcap_open_live(...);
我强烈建议不要使用线程,除非你必须这样做
问题是,您必须非常小心,以避免竞争条件和其他同步问题。例如,您的GUI框架库可能不希望从多个线程调用,因此您的//show packets here
例程可能会将其弄糊涂
如果可能的话,我会建议从主线程读取数据包。你不说你使用的是哪个GUI框架;既然你使用C++,我会假设QT,因为这是很常见的,但是所有其他的框架都有类似的功能。
您需要做的是:
- 调用pcap_setnonblock()将捕获描述符置于非阻塞模式
- 调用pcap_get_selective_fd()获取用于监视事件的文件描述符
- 使用对象(将上一步中的文件描述符作为套接字参数传递)监视文件描述符中的事件
- 当事件激发时,调用pcap_dispatch()以分派数据包
- 为了获得最大的可移植性,还可以在计时器上调用pcap_dispatch(),因为select()在某些操作系统的pcap套接字上无法正常工作
(至于您的代码当前崩溃的原因-请注意,您可能希望将处理程序
而不是处理程序
作为pthread_create()
的参数传递给pthread_create()。但只是修复这一问题以后可能会导致奇怪的不可靠性-因此,使用单线程几乎肯定是前进的方向!)我强烈建议不要使用线程,除非您必须这样做
问题是,您必须非常小心,以避免竞争条件和其他同步问题。例如,您的GUI框架库可能不希望从多个线程调用,因此您的//show packets here
例程可能会将其弄糊涂
如果可能的话,我会建议从主线程读取数据包。你不说你使用的是哪个GUI框架;既然你使用C++,我会假设QT,因为这是很常见的,但是所有其他的框架都有类似的功能。
您需要做的是:
- 调用pcap_setnonblock()将捕获描述符置于非阻塞模式
- 调用pcap_get_selective_fd()获取用于监视事件的文件描述符
- 使用对象(将上一步中的文件描述符作为套接字参数传递)监视文件描述符中的事件
- 当事件激发时,调用pcap_dispatch()以分派数据包
- 为了获得最大的可移植性,还可以在计时器上调用pcap_dispatch(),因为select()在某些操作系统的pcap套接字上无法正常工作
(至于您的代码当前崩溃的原因-请注意,您可能希望将处理程序
而不是处理程序
作为pthread_create()
的参数传递给pthread_create()。但只是修复这一问题以后可能会导致奇怪的不可靠性-因此,使用单线程几乎肯定是前进的方向!)