Anzeige:
Ergebnis 1 bis 15 von 15

Thema: probs mit fork()

  1. #1
    Registrierter Benutzer
    Registriert seit
    26.07.2002
    Ort
    Mittelfranken
    Beiträge
    150

    probs mit fork()

    Hallo,

    Habe eine Fkt. in der in den ersten Zeilen ein Socket erstellt wird, und dann zu einem rechner connected wird.
    Schlägt das connecten fehl, starte ich per fork() und execvp einen neuen Prozess, schliesse den bereits geöffneten fd (socket), warte einige Sekunden, und connecte erneut.
    Mein Problem an der Sach ist nun, dass wenn ich das Programm, das ich via execvp und dem erzeugten Prozess beende, startet es sich automatisch immer wieder!
    Irgendwie wird immer wieder der code vor dem fork aufruf ausgeführt! Also dann socket(), connecte() und da ja dann connecten fehlschlägt, wird wieder das Programm gestartet!

    Wieso führt der Rechner den Code vor dem fork aufruf immer wieder aus, wenn ich das aufgerufene Programm beende?

  2. #2
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Vielleicht kommt der Kindprozess in de selben Codeteil, wie der Elternprozess.

    nach dem Fork weißt du ja anhand des fork Rückgabewertes, ob du im Kind oder im Elternprozess bist.

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  3. #3
    Registrierter Benutzer
    Registriert seit
    26.07.2002
    Ort
    Mittelfranken
    Beiträge
    150
    Denke am besten ich poste mal den code:


    Code:
    int checken(char *message)
    {
      
      struct sockaddr_in client; 
      int sock ;
      
      pid_t pid;
    
      client.sin_family = AF_INET;                                          
      client.sin_port = htons(PORT_SENDEN_XPROG);                                 
      //client.sin_addr.s_addr = inet_addr("127.0.0.1");
      client.sin_addr.s_addr = INADDR_ANY;
    
      if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)                      
        { 
          printf("\nFehler beim Erstellen des Socket im client!\n"); 
         
          return -1;
        } 
      else
        {
          printf("\nSocket 1 vor fork Aufruf wurde erfolgreich erstellt im client!");
        }
      
      
      if (connect(sock, &client, sizeof(client)) < 0)                         
        {
          printf("\nconnect() 1 (pruefen ob xprog laeuft) failed!");
                
          close(sock);
          
          switch(pid=fork())
    	{
    	case -1:
    	  {
    	    puts("fork() failed!");
    	    return -1;
    	    break;
    	  }
    	  
    	case 0:
    	  {// Kind
    	    puts("\nStarte xprog!");
    	    execvp(PFAD_XPROG, NULL);
    	    break;
    	  }
    	  
    	default:
    	  {// Eltern
    	    puts("warten...");
    	    sleep(3);
    	    senden_xprog(message);
    	    break;
    	  }
    	}
          puts("\n Nach switch() \n");
        }
      
      else
        {
          
          printf("\nConnect war erfolgreich!");
          puts("sende sofort!");
    
          close(sock);
          senden_xprog(message);
            
          return 0;
        }
      
      
      return 0;
    }
    Wie gesagt, wenn das Programm durch execvp gestartet wurde, und ich es dann beede, wird es immer wieder gesartet! Es wird also der Code oberhalb der switch Anweisung immer wieder ausgeführt!
    Geändert von mithras (01-10-2002 um 17:18 Uhr)

  4. #4
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    was macht das PFAD_XPROG, das ist ein anderes Programm, oder?

    Außerdem solltest du im Parent vielleicht einfach einen neuen Connect Versuch machen, praktisch das if(connect ... in einer Schleife ausführen.

    Das senden_xprog(message); riecht nach Rekursion

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  5. #5
    Registrierter Benutzer
    Registriert seit
    26.07.2002
    Ort
    Mittelfranken
    Beiträge
    150
    jo PFAD_XPROG, ist der PFAD zu einem Programm.

    Wie meinst du das mit der Rekursion, wie kann ich das beheben?

    Dachte mir, ich könnte das Prob. event auch mit Signals lösen !?

  6. #6
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Mit Rekursion meinte ich, dass dieses
    senden_xprog(message);
    so aussieht als würde es im Laufe des Codes wieder
    int checken(char *message)
    aufrufen, also eine kaskadierte Rekursion.

    Der Code von checken sieht so aus, als sollte er folgendes machen:
    versuchen zu einem Prozess zu connecten.
    Wenn das fehlschlägt, diesen Porzess starten und erneut versuchen zu connecten.
    Sowas würde man natürlich sinnvoller Weise in einer Schleife machen.

    Aber wahrscheinlich hab ich die beabsichtigte Funktionalität nicht verstanden.

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  7. #7
    Registrierter Benutzer
    Registriert seit
    26.07.2002
    Ort
    Mittelfranken
    Beiträge
    150

    Der Code von checken sieht so aus, als sollte er folgendes machen:
    versuchen zu einem Prozess zu connecten.
    Wenn das fehlschlägt, diesen Porzess starten und erneut versuchen zu connecten.
    Ja du hast recht, so war das gedacht!

    Ich hab das Problem immernoch und bin am verzweifeln!
    Dein Argument mit der rekursion verstehe ich aber nicht ganz, denn in der Fkt. senden_xprog(message); rufe ich eigentlich die Fkt. checken nicht auf. Hab den Code von senden_xprog(message) angehängt:

    Code:
    int senden_xprog(char *message)
    {
      struct sockaddr_in client; 
      int sock, bytes;
      
      client.sin_family = AF_INET;                                          
      client.sin_port = htons(PORT_SENDEN_XPROG);                                 
      //client.sin_addr.s_addr = inet_addr("127.0.0.1");
      client.sin_addr.s_addr = INADDR_ANY;
      
      if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)                      
        { 
          printf("\nFehler beim Erstellen des Socket! in Fkt. senden_xprog\n"); 
          return -1;
        } 
      else
        {
          printf("\nSocket wurde erfolgreich erstellt in Fkt. senden_xprog!");
        }
      
      if (connect(sock, &client, sizeof(client)) < 0)                      
        {
          perror("connect() failed senden_xprog_right "); 
          close(sock);
        }
      
      else
        {
          bytes = send(sock, message, strlen(message), 0);
          
          if (bytes == -1)
    	{
    	  perror("send() failed in Fkt. senden_xprog_right");
    	  return -1;
    	}
          else
    	{
    	  printf("\nClient: %s an Server geschickt!\n in Fkt. senden_xprog_right", message);
    	}
          
          close(sock);
        }
    
      return 0;
    }

  8. #8
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Original geschrieben von mithras
    Ja du hast recht, so war das gedacht!

    Ich hab das Problem immernoch und bin am verzweifeln!
    Dein Argument mit der rekursion verstehe ich aber nicht ganz, denn in der Fkt. senden_xprog(message); rufe ich eigentlich die Fkt. checken nicht auf. Hab den Code von senden_xprog(message) angehängt:
    Ich sagte ja, es "riecht" nach Rekursion.
    Ich kannte ja den Code nicht.

    Hmm, hab leider keine Idee, was da schiefläuft.

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  9. #9
    Registrierter Benutzer
    Registriert seit
    14.09.2002
    Ort
    Bruchsal
    Beiträge
    164
    die funktion execvp wird falsch aufgerufen (du musst dem aufzurufenden programm als 1. parameter seinen eigenen namen mitgeben) und falls diese fehlschlägt hast du plötzlich zwei gleiche prozesse (der kindprozess wird nicht beendet).

    Probiers mal so (änderungen sind fett):
    Code:
    case 0:
    {// Kind
       puts("\nStarte xprog!");
       execvp(PFAD_XPROG, PFAD_XPROG, NULL);
       _exit(1);
       break;
    }

  10. #10
    Registrierter Benutzer
    Registriert seit
    26.07.2002
    Ort
    Mittelfranken
    Beiträge
    150
    habe deine tipps eingebaut,

    execvp(PFAD_XPROG, PFAD_XPROG, NULL);
    _exit(1);

    dann kommt aber beim kompelieren das:

    client_fkt.c:271: too many arguments to function `execvp'

  11. #11
    Registrierter Benutzer
    Registriert seit
    14.09.2002
    Ort
    Bruchsal
    Beiträge
    164
    ups, execvp nimmt ja ein array entgegen
    benutze stattdessen mal execlp() mit obiger syntax

  12. #12
    Registrierter Benutzer
    Registriert seit
    26.07.2002
    Ort
    Mittelfranken
    Beiträge
    150
    ich mach das ganze nu so (wie ripper mir empfohlen) hat aber hab immer noch das gleiche prob. ? irgendwie scheint dieser bug ziemlich tricky zu sein!? über jede lösungsmögliuchkeint würde ich mich freuen!

    Code:
    case 0:
    	  {// Kind
    	    puts("\nStarte xprog!");
    	    //execvp( PFAD_XPROG, NULL);
    	     execlp(PFAD_XPROG, PFAD_XPROG, NULL);
    	    _exit(1);
    	    break;
    	  }

  13. #13
    Registrierter Benutzer
    Registriert seit
    14.09.2002
    Ort
    Bruchsal
    Beiträge
    164
    naja, der programmcode tut bei mir eigentlich das was er soll (zumindest soweit ich ihn hab )
    vielleicht zeigt PFAD_XPROG ja auf dein programm hier und er startet dieses immer wieder?

  14. #14
    Registrierter Benutzer
    Registriert seit
    26.07.2002
    Ort
    Mittelfranken
    Beiträge
    150
    hm deinen letzten Satz hab ich nicht so ganz verstanden.
    PFAD_XPROG ist der Pfad zu dem Prog. das gestartet werden soll. Jo das Problem ist dass wenn ich das gestartete Programm schliesse, es immer wieder gestartet wird!

  15. #15
    Registrierter Benutzer
    Registriert seit
    14.09.2002
    Ort
    Bruchsal
    Beiträge
    164
    sorry, ohne weitere informationen kann ich dir nicht mehr weiterhelfen, vielleicht kommst du dem bug mit einem debugger (gdb; ich empfehle ddd als grafisches front-end) auf die spur.

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •