2017-06-12 29 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