2016-05-17 102 views
0

我已經寫了最簡單的原始套接字示例通過RAW套接字發送數據從一個應用程序到另一個protcol no = 5(未被標準協議使用)。沒有正確的數據正在接收原始套接字

這裏是我的代碼:

發件人

void sendRawData(char sendString[]) 
{ 

    int sock; 
    struct sockaddr_in server_addr; 
    struct hostent *host;     //hostent predefined structure use to store info about host  host = (struct hostent *) gethostbyname(server);//gethostbyname returns a pointer to hostent 
    if ((sock = socket(AF_INET, SOCK_RAW, 5)) == -1) 
    { 
      perror("socket"); 
      exit(1); 
    } 

    //destination address structure 
    server_addr.sin_family = AF_INET; 
    server_addr.sin_port = htons(NOT_REQ); // NOT_REQ is 2000 but for SOCK_RAW sockets, it should be useless. 
    server_addr.sin_addr = *((struct in_addr *)host->h_addr);  //host->h_addr gives address of host 
    bzero(&(server_addr.sin_zero),8); 
    sendto(sock, sendString, strlen(sendString), 0,(struct sockaddr *)&server_addr, sizeof(struct sockaddr)); 

    //sendto() function shall send a message through a connectionless-mode socket. 
    printf("\nFORWARD REQUEST : '%s' has been forwarded to server\n",sendString); 
    close(sock); 
} 

reciever

int main(int argc, char **argv){ 
    int sock = 0, len, addr_len; 
    char rec_buff[5000]; 

    struct sockaddr_in address, 
        server_addr_udp, 
        client_addr; 

    if ((sock = socket(AF_INET, SOCK_RAW, 5)) == -1)   //Creating a UDP Socket 
    { 

      perror("Socket"); 
      exit(1); 
    } 

    server_addr_udp.sin_family = AF_INET; 
    server_addr_udp.sin_port = htons(2004); // again it should be useless 
    server_addr_udp.sin_addr.s_addr = INADDR_ANY; 
    bzero(&(server_addr_udp.sin_zero),8); 
    addr_len = sizeof(struct sockaddr); 
    if (bind(sock,(struct sockaddr *)&server_addr_udp, sizeof(struct sockaddr)) == -1)//Binding UDP socket 
    { 
     perror("Bind"); 
     exit(1); 
    } 

    len = recvfrom(sock, rec_buff,5000,0,(struct sockaddr *)&client_addr, &addr_len); 
    printf("ip = %s, port = %d\n", inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port)); 
    printf("%s\n", rec_buff); 
    main(0, NULL); 
    return 0; 
} 

什麼,我觀察是在接收端,我收到了不正確的數據。 如果我更改套接字類型SOCK_DGRAM和協議= IPPROTO_UDP,那麼一切工作完美。 我的意圖是使用自定義協議號(5),因爲世界上的每個數據包都不需要是UDP/TCP數據包。

有人能指教我哪裏出錯了。

輸出

ip = 127.0.0.1, port = 0 
E 
+0

我推薦開始檢查'len'(你的讀取字節數)以及'sendto'實際發送的字節數。也請擺脫那些討厭的'bzero's。 – SergeyA

+0

我打印由sendto和recv來重新調整的值。 FORWARD REQUEST:'你好,我是發件人'已被轉發到服務器,rc = 18(由sendto返回的值是正確的) 在接收方:它是38. –

回答

1

答案是出奇的簡單:)。當您收到原始IP數據報時,它始終包含IP標頭。 (提示 - 檢查返回值recvfrom()並將其與返回值sendto()進行比較將幫助您實現此目的,正如我在之前的評論中所指出的那樣)。

因此,您可以正確解析IP標頭以獲得有效負載,或者您可以假設IP標頭大小始終爲20個字節,並且只需快速轉發即可。

+0

這確實解決了問題。非常感謝.... –