2011-01-01 4 views
0

사용자가 네트워크를 검색 할 수있는 GUI 프로그램이 있는데 문제는 pcap_loop 함수가 호출 될 때 GUI 프로그램이 응답하지 않는 것입니다 (pcap_loop가 현재 스레드를 차단 함).스레딩 및 pcap 문제

pthreads를 사용하려고하면 pcap_loop 함수에서 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. 

답변

1

"&"이 훨씬 적습니다. 유형 pcap_t **이 될 것 &handle를 사용

 
pcap_t *handle = pcap_open_live(...); 

가정하지만, 스레드 기능이 다시 캐스트 것은 그것을 사용하는 경우 정의되지 않은 동작에 이르게 pcap_t *에 (그런데 캐스트도/무의미한 중복), 보통이다 잘못 될 것입니다. 더 나은 :

 
static void *pcap_looper(void *arg) 
{ 
     pcap_t *handle = arg; 

     /* etc. */ 

     return NULL; 
} 

int main(void) 
{ 
     pcap_t *handle; 
     pthread_t tid; 
     int ret; 

     handle = pcap_open_live(...); 
     ret = pthread_create(&tid, NULL, pcap_looper, handle); 
     ... 
     pthread_join(tid, NULL); 
     return EXIT_SUCCESS; 
} 
3

절대적으로해야하지 않는 한 스레드를 사용하지 않는 것이 좋습니다.

문제는 경쟁 조건 및 기타 동기화 문제를 피하기 위해 매우주의해야한다는 것입니다. 예를 들어 GUI 프레임 워크 라이브러리는 여러 스레드에서 호출 될 것으로 예상되지 않으므로 //show packets here 루틴이이를 혼동시킬 수 있습니다.

가능한 경우 주 스레드에서 패킷을 읽는 것이 좋습니다. 당신은 어떤 GUI 프레임 워크를 사용하고 있는지 말하지 않는다. 왜냐하면 당신은 C++을 사용하고 있기 때문에 Qt는 꽤 일반적이기 때문에 가정 할 것이지만 다른 모든 프레임 워크는 비슷한 기능을 가지고 있습니다.

당신이해야 할 것은 :

  • 통화 pcap_setnonblock은() 이벤트를 모니터링하는 파일 기술자를 얻기 위해 비 블록 모드에서
  • 통화 pcap_get_selectable_fd()을 캡처 설명을 넣어
  • QSocketNotifier 객체 (소켓 매개 변수로 이전 단계의 파일 설명자 전달)를 사용하여 이벤트에 대한 파일 설명자를 모니터하십시오.
  • 이벤트가 발생하면 pcap_dispatch()를 호출하여 패킷을 디스패치하십시오.
  • 최대 이식성을 위해 select()가 일부 OS의 pcap 소켓에서 제대로 작동하지 않기 때문에 타이머에서 pcap_dispatch()를 호출하십시오.

은 (코드는 현재 충돌 이유에 관해서는 - 당신은 아마 pthread_create()에 매개 변수로 handler보다는 &handler을 전달하려는 있습니다하지만 그냥 나중에 이상한 신뢰성 발생할 수 있습니다 고정 -. 그래서 단일 스레드 것입니다 거의 확실한 방법!)