C++ 线程和pcap问题

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

我有一个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
}
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()。但只是修复这一问题以后可能会导致奇怪的不可靠性-因此,使用单线程几乎肯定是前进的方向!)