2017-06-13 47 views
0

我想使用多线程来捕获和处理IP数据包。一个线程将只捕获并存储数据包,例如2秒钟,然后发送(使用管道)这个数据块到另一个线程,以便提取必要的信息。捕获ip数据包,使用RAW套接字和recvfrom(),但recvfrom()为每个循环迭代返回-1。我认为套接字没有捕获数据包,但我无法找出原因......任何帮助?这里是代码...recvfrom()在线程中使用时返回-1的RAW套接字?

void Capture() 
{ 
    int rbytes, Rsock; 

    struct sockaddr saddr; 

    unsigned char *buffer = (unsigned char *)malloc(65536); /* hold packet */ 

    /* Create a raw socket that shall sniff */ 
    Rsock=socket(AF_PACKET , SOCK_RAW , htons(ETH_P_IP)); 
    if(Rsock < 0) 
    { 
     printf("Socket Error\n"); 
     return; 
    } 

    while(1) 
    { 
     rbytes = recvfrom (Rsock , buffer , 65536 , 0 , &saddr ,(socklen_t *)sizeof saddr); 
     if(rbytes <=0) 
      printf("failed to get packets!"); 
     else 
      printf("Recv bytes %d: \n", rbytes); 
    } 
} 

,并在main()是..

int main() 
{ 
    pthread_t tid; 

    int err = pthread_create(&(tid), NULL, (void*)&Capture, NULL); 
     if (err != 0){ 
      printf("\ncan't create capturing thread :[%s]", strerror(err)); 
      return 0; 
     } 
     else 
      printf("\nCapturing thread created!\n"); 

    pthread_join(tid, NULL); 

    printf("Finished!!"); 
    return 0; 
} 
+1

为什么不检查['errno'](http://man7.org/linux/man-pages/man3/errno.3.html)以查看*出错* –

回答

1

你的最后两个参数在这里是错误的,

rbytes = recvfrom (Rsock , buffer , 65536 , 0 , &saddr ,(socklen_t *)sizeof saddr); 

不要投最后一参数,你需要通过一个实际的指针。你还需要传递一个指向特定sockaddr类型的指针,而不是指向struct sockaddr的指针以及可能需要投射的参数。

struct sockaddr_storage saddr; //Or sockaddr_in if you are certain you 
           // only deal with IPv4... 
socklen_t slen = sizeof saddr; 

rbytes = recvfrom (Rsock , buffer , 65536 , 0 , (struct sockaddr*)&saddr ,&slen); 

如果recvfrom的返回-1,你可以检查errno值来学习什么是错的,或只是打印与例如错误perror("recvfrom failed");

+0

完美答案...谢谢 – mohtashim

相关问题