Hallo Perlgemeinde!
Ich knoble an einem Problem:
Ich muß zur Steuerung eines Gerätes per TCP ein Kommando (ASCII) senden, die Antwort lesen und ausgeben und die Antwort per Timer überwachen.
Meine Idee dazu siehe unten (nur ein Ausschnitt). Es wird ein Socket geöffnet, per fork ein neuer Prozess gestartet. Der "schnellere" Prozess killt jeweils den anderen und beendet sich dann: Der ElternProzess sendet das Kommando ($command + 0x0d 0x0a 0x00), empfängt die Antwort, killt den Timerprozess und beendet sich, der Timerprozess lauert auf das Ende von sleep und killt den Sender/Empfänger Prozess und beendet sich auch. Das ganze läuft als EXE (das Thema des Threads stimmt also nicht ganz), erstellt mit Perl2Exe V8.00 und ActivState Perl v5.8.2 Build 808 unter WinXP und wird in regelmäßigen Abständen aus einem Batchfile aufgerufen.
Manchmal, eher selten, bleibt nun die exe hängen, braucht 50% Prozessorlast und kann nur noch per Taskmanager abgeschossen werden. Ein Etherealtrace zeigt, daß die Kommunikation zw. PC und Target eigentlich erfolgreich war. Jetzt die Frage: Liegts an meiner Implementierung, an Perl oder Perl2Exe, an WinXP? Im Taskmanager kann man nicht erkennen, um welchen der beiden Prozesse es sich handelt.
Vielleicht könnt Ihr einen Fehler entdecken? Oder habt eine andere Idee. Dafür schon mal vielen Dank!
Gruß Frank
[...]
init Vars
read Parameter
[...]
Socket öffnen
$socket = new IO::Socket::INET(
PeerAddr => $target,
PeerPort => $PORT,
Proto => 'tcp',
) or die "Can't connect target $target!";
eigene ID merken
$ParentId = $$;
Prozess für Timer erzeugen
$TimerPid = fork();
die "fork: $!" unless defined $TimerPid;
if ($TimerPid) {
# command an target senden
print $socket "$command \x0d\x0a\0x00";
# antwort lesen und ausgeben, Endekennzeichen ist 0x0a
while ($char ne "\x0a") {
$char=$socket->getc();
print $char;
}
$socket->close();
# Timer Prozess killen
kill("KILL",$TimerPid);
}else{
sleep ($timeout);
print "Timeout! No answer from target $target!\n";
$socket->close();
# Elternprozess killen
kill("KILL",$ParentId);
}
exit;