2017-06-12 1 views
2

Ich versuche, ein UDP-Datagramm von einem Linux-Computer an eine IP-Kamera zu senden, um es zu erkennen. Alle Geräte sind über einen Switch verbunden.UDP kann nicht von einem Linux-Computer an eine Multicast-Gruppe gesendet werden

Es gibt eine mit dieser Kamera kompatible Windows-App, die ein UDP-Datagramm an eine Multicast-Gruppe sendet und eine Antwort von der Kamera über dieselbe Gruppe erhält. Ich habe das über Wireshark herausgefunden und beschlossen, das gleiche Datagramm aus einem C-Programm auf meinem Linux-Rechner zu senden. Ich kann die richtige Antwort erhalten, wenn mein C-Programm es direkt an die IP-Adresse der Kamera sendet, aber nicht, wenn ich es an die Multicast-Gruppe sende.

Ich habe daher ein Listener-Programm auf meinem Linux-Computer erstellt und versucht, es an die Multicast-Adresse zu senden. Das ist gelungen, aber in Wireshark habe ich nichts gefunden.

So scheint es, dass mein C-Programm in der Lage ist, das Datagramm korrekt zu senden, nur nicht auf das Netzwerk. Kann dies eine Art von Linux-Konfiguration sein?

EDIT: Wie angefordert, hier ist der Code. Zu Ihrer Information: Ich versuche nur, Daten an die Kamera zu senden und die Reaktion in Wireshark zu untersuchen.

#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() von udp_socket.h:

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

Das ist natürlich sehr schwer ohne Ihren Code, aber haben Sie die Multicast-Gruppe zuerst in Ihrem Linux-Programm * beitreten? – unwind

+2

Multicast muss auf der Netzwerkschnittstelle erlaubt sein. Probieren Sie den Befehl 'ifconfig eth0 multicast' (ersetzen Sie eth0 durch Ihre Adapter-ID). – Marian

+0

Können Sie Ihren Code anhängen? –

Antwort

0

Wenn Multicast-Datagramme zu senden, werden sie normalerweise auf der Schnittstelle je nachdem, was Netz gesendet werden, wird die Standard-Schnittstelle betrachtet.

Wenn dies nicht die Schnittstelle ist, die Sie senden möchten, müssen Sie die ausgehende Multicast-Schnittstelle konfigurieren. Dies geschieht mit der Option IP_MULTICAST_IF:

Wenn Sie beispielsweise Multicast von der Schnittstelle mit IP 192.168.1 senden möchten.1, Sie richten es wie folgt ein:

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

Vielen Dank, liebe Fremder. – Cortex

0

Die folgenden vorgeschlagenen Code:

  1. kompiliert sauber.
  2. führt die gewünschte Operation (Senden eines UDP-Pakets).
  3. überprüft ordnungsgemäß den zurückgegebenen Status des Anrufs an sendto().
  4. überprüft ordnungsgemäß den zurückgegebenen Status des Anrufs an socket().
  5. enthält keine Header-Dateien, deren Inhalt nicht verwendet wird.
  6. erwartet, dass sich die Multicast-Adresse in der Systemroute-Tabelle befindet.
  7. Hinsicht die Breite der gedruckten Seite
  8. fügt die fehlenden #include für den Anruf zu printf().
  9. fügt das fehlende #include für den Anruf memset() hinzu.
  10. richtig ausgibt Fehlermeldungen an stderr

und jetzt den vorgeschlagenen Code:

#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

Obwohl dies mein Problem nicht löste, war es hilfreich, so wie ich es bin nicht sehr erfahren mit C. – Cortex

Verwandte Themen