UDP - senden/empfangen funktioniert nicht

matt

Erfahrenes Mitglied
hi leute!

mit meinem client-server programm bin ich nun weiter gekommen und sowohl der server als auch der client läuft nun. der UDP-client schickt in abständen von 10 sekunden eine nachricht an den server. die nachricht kommt am server auch an (getestet mit tcpdump). auch der server hört am richtigen UDP-port (ebenfalls getestet, der server war in der auflistung dieses linux-programms aufgelistet). nur die nachricht wird irgendwie nicht eingelesen. ich habe mich nun gestern mit einem kollegen ca. 2h hingesetzt und wir sind das zusammen durchgegangen, aber ohne erfolg. vielleicht kann mir jemand helfen?




der code in main() bis zum funktionsaufruf der funktion, die für das empfangen der UDP-daten zuständig ist:
Code:
  int udpsocket, ret_recv;
  struct sockaddr_in srv;

  udpsocket = socket(AF_INET, SOCK_DGRAM, 0);
  if (udpsocket == -1) {
    perror("Fehler in socket()");
    return 2;
  }

  srv.sin_family = AF_INET;
  srv.sin_addr.s_addr = INADDR_ANY;
  srv.sin_port = htons( (unsigned short int) atol(argv[2]));

  if (bind(udpsocket, (struct sockaddr *)&srv, sizeof(srv)) != 0) {
    perror("Fehler in bind()");
    return 3;
  }

  do {
    verbose("recvUDPdata folgt");
    ret_recv = recvUDPdata(udpsocket, &message_in, &srv);

die funktion, die für das empfangen der UDP-daten zuständig ist:
Code:
int recvUDPdata(int socket, char **return_buffer, struct sockaddr_in *from) {
  int totalbytes, bytes, from_size;
  char *recv_buffer;
  struct sockaddr_in remoteaddr;

  from_size = sizeof(remoteaddr);

  totalbytes = 0;
  do {
       *return_buffer = realloc(*return_buffer, totalbytes + BUFFER_SIZE);
    if (*return_buffer == NULL) {
      fprintf(stderr, "realloc liefert NULL\n");
      exit(1);
    }
    recv_buffer = &((*return_buffer)[totalbytes]);

    DEBUG(printf(">> start recvfrom\n"));
    bytes = recvfrom(socket, recv_buffer, BUFFER_SIZE, 0, (struct sockaddr *)&remoteaddr, &from_size);
    // bytes = recvfrom(socket, recv_buffer, BUFFER_SIZE, 0, NULL, 0);
    DEBUG(printf(">> end recvfrom (%i)\n", bytes));
    if (bytes == -1) {
      if (errno == ECONNRESET || errno == 0) {
        return -1;
      } else {
        fprintf(stderr, "Fehlercode: %i\n", errno);
        perror("recv() fehlgeschlagen");
        return 0;
      }
    }
    totalbytes += bytes;
  } while (!bytes || recv_buffer[bytes - 1] != '\0');

  DEBUG(printf("<< %s\n", *return_buffer));

  return 1;
}

hoffe, dass mir jemand weiterhelfen kann. :)

gruß,
matt
 
Zuletzt bearbeitet:
kann mir denn niemand weiterhelfen? :( sorry dass ich das schreibe... ich habe heute den halben tag versucht, das irgendwie in den gang zu bekommen, aber es klappt einfach nicht.

hat denn nicht jemand nur eine kleine idee? vielleicht wäre mir damit auch schon etwas geholfen.

matt
 
Hi,
es ist schwer auf anhieb den Fehler zu finden wenn man den Server selber nicht laufen hat.
Aber vielleicht versuchst du einfach mal mit dem gdb den Server speziell die funktion
recvUDPdata durchzudebuggen und alle werte zu vergleichen, wenn dus nicht schon gemacht
hast.
Ansonsten kann ich dir leider auch keinen Tip geben.

MfG
RedWing
 
hi!

erstmal danke für die antwort :)

was ist denn der gdb? noch nie etwas davon gehört... ansonsten, wenn du mir helfen möchtest, kann ich dir gerne den server und evtl. auch den client zukommen lassen, wenn du den auch zum testen brauchst. mein problem ist, dass ich im moment damit überhaupt nicht weiterkomme und keine ahnung habe, woran das liegen könnte, dass das teil nicht . ich bin leider recht neu auf dem c-gebiet.

gruß,
matt
 
Hi Matt,
der gdb ist der Debugger von gnu, mit dem du Breakpoints setzen kannst und ein
Programm schritt für Schritt durchsteppen kannst und somit jeden Wert vergleichen
kannst.
Schau dir einfacj mal die Manuals an.

P.S. Kannst mir deine Sourcen (Server und client) ja mal an meine Mail schicken und wenn ich Zeit hab kann ichs mir ja mal angucken.

MfG RedWing
 
jetzt klappt's!

hi RedWing & mitleser,

ich habe den server nun auf einem anderen linux-system laufen lassen, da ich dort den gdb drauf hatte. komischerweise lief der server dort ohne dieses problem. ich werde bei nächste gelegenheit mal nachschauen, ob das problem evtl. an den sicherheitseinstellungen liegen kann.

vielen dank!
matt
 
Hi Matt,

bist Du sicher, dass Deine recvfrom() korrekt (besonders in Bezug auf UDP) ist, um Daten zu lesen?

Versuche es mal mit recv()... Ich habe bei UDP-Messages leider auch nur wenig Erfahrung. Allerdings habe ich mit einem Kollegen mal eine Client-/Server-Anwendung (ein Messenger für unser firmeninternes Intranet) geschrieben, bei welchem wir die Daten mit recv() korrekt empfangen konnten.

Nachtrag:
Ich habe gerade einen Hinweis gefunden, dass bei jedem Aufruf von recvfrom() bei UDP die Remote-Adresse des Servers mitgegeben werden muß.

Viel Glück
René
 
Zuletzt bearbeitet:
hi rene,

da ich kein connect()-aufruf habe, muss ich recvfrom benutzen.

laut der man-page von linux wird in "from" die quell-adresse eingefügt. empfangen kann ich damit dann auch korrekt, das ist nicht das problem. jedenfalls ist es das nicht offensichtlich. das problem, welches ich jetzt noch habe, ist ein speicherleck. ich hab's allerdings noch nicht gefunden. möglicherweise liegt es auch irgendwo an dieser stelle, aber alles, was ich bisher getestet hab, hat nichts gebracht.

RECV(2)
int recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr
*from, socklen_t *fromlen);

DESCRIPTION
[...]

If from is not NULL, and the socket is not connection-oriented, the
source address of the message is filled in. The argument fromlen is a
value-result parameter, initialized to the size of the buffer associ-
ated with from, and modified on return to indicate the actual size of
the address stored there.

@RedWing: werde dir mal den code zukommen lassen, heute geht es allerdings nicht. bin heute den rest des tages unterwegs.

matt
 
Zurück