PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : probs mit fork()



mithras
01-10-2002, 16:45
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?

anda_skoa
01-10-2002, 17:14
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,
_

mithras
01-10-2002, 17:16
Denke am besten ich poste mal den 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!

anda_skoa
01-10-2002, 18:01
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,
_

mithras
02-10-2002, 17:16
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 !?

anda_skoa
02-10-2002, 17:25
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,
_

mithras
04-10-2002, 16:25
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:



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;
}

anda_skoa
04-10-2002, 17:41
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,
_

The Ripper
05-10-2002, 14:19
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):


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

mithras
05-10-2002, 17:24
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'

The Ripper
06-10-2002, 18:39
ups, execvp nimmt ja ein array entgegen ;)
benutze stattdessen mal execlp() mit obiger syntax

mithras
11-10-2002, 18:01
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!




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

The Ripper
11-10-2002, 18:27
naja, der programmcode tut bei mir eigentlich das was er soll (zumindest soweit ich ihn hab :D)
vielleicht zeigt PFAD_XPROG ja auf dein programm hier und er startet dieses immer wieder?

mithras
11-10-2002, 20:39
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!

The Ripper
12-10-2002, 13:17
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.