Pipe - Daten werden nicht sauber übertragen



  • Hi!

    Ich habe ein Problem mit meinem Daemon für ein Spiel. Die Daten dieses Daemons kommen über einen Socket rein. Bisher war das immer nur 1 Long-Wert, welchen ich mittels Pipe an einen Thread übertragen habe, der mittels select auf einen Timeout oder einen Datensatz über die Pipe gewartet hat.

    Jetzt wollte ich das ganze erweitern, damit ich zu einem Datensatz noch Zusatzinformationen übertragen kann.

    Irgendwo mache ich aber was falsch. Es wird nur der erste Datenblock gelesen und das war es dann.

    Hier mal der Sende-Code:

    std::getline(in, line);
    buffer = strdup(line.c_str());
    nwrite = write (queue_pipe[1], buffer, strlen(buffer)+1);
    
    std::getline(in, line);
    buffer = strdup(line.c_str());
    nwrite = write (queue_pipe[1], buffer, strlen(buffer)+1);
    
    std::getline(in, line);
    buffer = strdup(line.c_str());
    nwrite = write (queue_pipe[1], buffer, strlen(buffer)+1);
    

    Die Rückgabewerte von write stimmen. Es wird immer genau die richtige Menge Daten übertragen. Ich habe nur der Einfachheit halber jetzt die Sicherheitsabfragen rausgenommen.

    Hier jetzt der Code, der nach dem select das ganze empfängt:

    nread = read(queue_pipe[0], buffer, 200);
    db_key  = string2long(buffer);
    
    nread = read(queue_pipe[0], buffer, 200);
    runtime  = string2long(buffer);
    
    nread = read(queue_pipe[0], buffer, 200);
    typ  = string2int(buffer);
    

    Beim ersten read wird nur der erste Block gelesen. Das klappt und die Daten sind korrekt.

    Nur die 2 folgenden read werden nicht mehr ausgeführt.

    Ich verstehe nicht, was ich genau falsch gemacht habe.

    Hier noch weitere Sourcezeilen, falls Fragen auftauchen wie ich die Pipe geöffnet habe:

    fd_set transfer_fds;
    int queue_pipe[2];
    
    // PIPE erstellen
    if (pipe(queue_pipe) == 0)
    {
      FD_ZERO (&transfer_fds);
      FD_SET(queue_pipe[1], &transfer_fds);
    }
    

    Hier jetzt noch das bereits erwähnte select

    res = select (FD_SETSIZE, &transfer_fds, (fd_set *)NULL, (fd_set *)NULL, &timeout);
    

    Wie schon geschrieben, wenn ich nur 1 Datensatz übertragen will, dann klappt es. Ich benötige aber leider jetzt 3 Datensätze für den Thread.

    Mir ist bekannt das ich auch über Sharedmemory und Semaphoren das ganze machen kann, aber da sich viele Tutorials wiedersprechen und jeder meint den Stein der Weisheit gefunden zu haben, bin ich einem Vorschlag eines Kollegen gefolgt, welcher sich mit der Thematik auskennt. Dummerweise ist jetzt Samstag und ich würde das ganze schon ganz gerne am Wochenende noch zum laufen bekommen 🙂

    Danke schonmal für die Hilfe!



  • gut, daß du nicht in c++ programmierst- dann wärst du total falsch im ansi-c forum.



  • Dr. Klug schrieb:

    gut, daß du nicht in c++ programmierst- dann wärst du total falsch im ansi-c forum.

    *g* Echt? 😉

    Falls du den Aufruf für die Socketkommunikation meinst, der ist egal. Mir geht es um die Pipes und die sind in C geschrieben bei mir.



  • Hallo,

    Also, ich weiß nicht, aber die Funktion read, sperrt solange bis sie angegebene Zeichen im Puffer empfangen hat.

    Reading Data from the Port

    Reading data from a port is a little trickier. When you operate the port in raw data mode, each read(2) system call will return however many characters are actually available in the serial input buffers. If no characters are available, the call will block (wait) until characters come in, an interval timer expires, or an error occurs.

    [...]

    Das ist lesen des RS232 Ports unter Linux.
    Jedoch gilt das für read allgemein.

    Wenn der erste read erfolgreich ist, hast du warscheinlich ein Zeit oder anders,
    Synchronisations Problem.

    Gruß Illu



  • Hi!

    Mein Fehler war ein ganz dummer Anfängerfehler...

    Ich lese 200 Bytes, aber (!) in den 200 Bytes (bzw. das was wirklich angekommen ist) sind ja alle 3 Strings drin!

    Das ich beim Output nur den 1. immer sehe liegt daran, daß die Strings ja mittels \0 Terminiert sind und die Outputroutinen danach logischerweise nicht mehr weiter machen.

    Blöder Fehler. Wirklich 😞


Anmelden zum Antworten