2017-06-12 31 views
2

我試圖從運行在Linux上的計算機向網絡攝像機發送UDP數據報以發現它。所有設備都通過交換機連接。無法從Linux計算機向組播組發送UDP

有一個Windows應用程序與此攝像頭兼容,它向組播組發送UDP數據報並通過相同的組從攝像機獲取答案。我通過Wireshark發現了這一點,並決定嘗試從我的Linux機器上的C程序發送相同的數據報。如果我的C程序直接將它發送到攝像機的IP地址,我能夠得到正確的響應,但如果我將它發送到多播組,則不能。

我爲此在我的Linux計算機上創建了一個偵聽器程序,並試圖將其發送到多播地址。這成功了,但我沒有在Wireshark中捕捉到任何東西。

因此,我的C程序似乎能夠正確地發送數據報,而不是出現在網絡上。這可能是某種Linux配置嗎?

編輯:根據要求,這裏是代碼。僅供參考:截至目前,我只是試圖將數據發送到相機並檢查Wireshark中的響應。從udp_socket.h

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <arpa/inet.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <fcntl.h> 
#include <errno.h> 

#include "udp_socket.h" 



int main(void) 
{ 

    //int s = udp_socket(50000); 
    int s = socket(AF_INET,SOCK_DGRAM,0); 
    printf("Socket: %d\r\n", s); 


    char buffer[48] = {0x67,0x45,0x00,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x67,0x45,0x00,0x00,0x14,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0xea,0xc8,0xc8,0xc8,0xf4,0xe6,0x00,0x00}; 
    struct sockaddr_in serveraddr; 
    memset(&serveraddr, 0, sizeof(serveraddr)); 
    serveraddr.sin_family = AF_INET; 
    serveraddr.sin_port = htons(59125);    
    serveraddr.sin_addr.s_addr = inet_addr("234.200.200.200"); 

    udp_socket_tx(s, buffer, sizeof(buffer), &serveraddr); 

    close(s); 
} 

udp_socket_tx():

int udp_socket_tx(int socket_fd, char * tx_buffer, int tx_buffer_len, const struct sockaddr_in * to_addr) { 

return sendto(
    socket_fd, 
    tx_buffer, 
    tx_buffer_len, 
    0, 
    (const struct sockaddr *)to_addr, 
    sizeof(struct sockaddr_in) 
); 

} 
+2

這當然是非常困難的沒有你的代碼,但你*加入*組播組首先在你的Linux程序? – unwind

+2

網絡接口上必須允許組播。嘗試命令'ifconfig eth0 multicast'(用適配器ID替換eth0)。 – Marian

+0

你可以附上你的代碼嗎? –

回答

0

當發送多播數據報,它們通常將哪個網絡接口被認爲是默認的接口上發送出去。

如果這不是您要發送的接口,則需要配置傳出多播接口。這是通過IP_MULTICAST_IF選項完成的:

例如,如果要從IP 192.168.1的接口發送多播。1,你的設置如下:

struct in_addr multi_interface; 
multi_interface.s_addr = inet_addr("192.168.1.1"); 
if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, 
       (char *)&multi_interface, sizeof(multi_interface)) == -1) { 
    perror("Error setting outgoing interface"); 
    close(s); 
    exit(1); 
} 
+0

謝謝親切的陌生人。 – Cortex

0

以下提出的碼:

  1. 完全編譯。
  2. 執行所需操作(發送UDP數據包)。
  3. 正確檢查呼叫的返回狀態爲sendto()
  4. 正確檢查呼叫的返回狀態爲socket()
  5. 不包含頭文件這些內容不被使用。
  6. 預計多播地址在系統'路由'表中。
  7. 尊重打印頁面的寬度
  8. 爲呼叫printf()添加缺少的#include
  9. 爲呼叫memset()添加缺少的#include
  10. 適當的錯誤消息輸出到stderr

,現在所提出的代碼:

#include <stdio.h>  // perror(), printf() 
#include <stdlib.h>  // exit(), EXIT_FAILURE, EXIT_SUCCESS 
#include <string.h>  // memset() 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <fcntl.h> 


int main(void) 
{ 
    int s = socket(AF_INET,SOCK_DGRAM,0); 
    if (0 > s) 
    { 
     perror("socket failed"); 
     exit(EXIT_FAILURE); 
    } 

    // implied else, socket successful 

    printf("Socket: %d\r\n", s); 

    unsigned char buffer[] = 
    { 
     0x67, 0x45,0x00,0x00,0x05,0x00,0x00,0x00,0x00,0x00, 
     0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 
     0x00, 0x00,0x00,0x00,0x14,0x00,0x00,0x00,0x67,0x45, 
     0x00, 0x00,0x14,0x00,0x00,0x00,0x0a,0x00,0x00,0x00, 
     0xea, 0xc8, 0xc8, 0xc8, 0xf4, 0xe6, 0x00, 0x00 
    }; 

    struct sockaddr_in serveraddr; 
    memset(&serveraddr, 0, sizeof(serveraddr)); 
    serveraddr.sin_family = AF_INET; 
    serveraddr.sin_port = htons(59125); 
    serveraddr.sin_addr.s_addr = inet_addr("234.200.200.200"); 

    ssize_t sendtoStatus = sendto 
    (
     s, 
     buffer, 
     sizeof(buffer), 
     0, 
     (const struct sockaddr *)&serveraddr, 
     sizeof(struct sockaddr_in) 
    ); 

    if(-1 == sendtoStatus) 
    { 
     perror("sendto failed"); 
     close(s); 
     exit(EXIT_FAILURE); 
    } 

    close(s); 
    return EXIT_SUCCESS; 
} // end function: main 
+0

雖然這並沒有解決我的問題,但它有幫助,就像我對C不是很有經驗。 – Cortex