2017-06-13 49 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

相關問題