timothy: anderes Programm ausführen

Hi folks

bei mir läuft ein Perlscript im Hintergrund.
Über einen Socket stellt ein "Client" eine Verbindung zu diesem Programm her. Darauf soll das "Hintergrundprogramm" etwas in ein Log-File schreiben und ein Fenster (Perl/TK) aufblenden.
soweit so gut.
Wird aber nun das aufgeblendete Fenster nicht geschlossen, so wartet das Hintergrundprogramm, bis eben dies passiert ist um dann weitere (eventuelle) Meldungen einzublenden/ins Log-File schreiben.

Ist nun das "erste"Meldungsfenster" lange auf dem BS, dann werden erst weitere Meldungen ins Log-File geschrieben, wenn diese Fenster geschlossen wurde. Auch wenn die nächste "Clientmeldung" schon lange anliegt.
Daraus ergibt sich das Problem, das die Zeit, die ebenfalls ins Log-File geschrieben wird, nicht mehr die aktuelle ist. Sondern die, wann das (nächste) medlungsfenster geschlossen wurde.

Also zB.

1. Clientkontakt -> Uhrzeit 12:30 -> Log-File wird (korrekt) geschrieben -> Meldungsfenster
                 popt auf

2. Clientkontakt -> Uhrzeit 12:45

Fälle:  a) vorheriges "PopUp" ist bereits geschlossen -> alles i.O.
          b) vorheriges PopUp noch auf dem BS und wird erst (z.B.) um 13:25 geschlossen,
             dann erfolgt der 2.Logfile-eintrag eben auch erst um 13:25 (statt 12:45)

Hier auch der Quelltext:

#!/usr/bin/perl

serverIO.pl - a simple server using

IO::Socket

use warnings;
use IO::Socket;
use Tk;
use IO::File;

Socket installieren

my $sock = new IO::Socket::INET(
                   LocalHost => [ heir der Hostname],
                   LocalPort =>  [hier der Port, an dem gelauscht wird],
                   Proto     => 'tcp',
                   Listen    => SOMAXCONN,
                   Reuse     => 1);

$sock or die "no socket :$!";
my($new_sock, $c_addr, $buf);

auf "Client-Kontakt" warten

while (($new_sock, $c_addr) = $sock->accept())
{
    my ($client_port, $c_ip) = sockaddr_in($c_addr);
    my $client_ipnum = inet_ntoa($c_ip);
    my $client_host = gethostbyaddr($c_ip, AF_INET);
    while (defined ($buf = <$new_sock>))
    {
  Zeit des "Kontaktes" ermitteln und formatieren
         ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
         $year = $year+1900;
         $sec = "0$sec" unless $sec > 9;
         $min = "0$min" unless $min > 9;
         $hour = "0$hour" unless $hour > 9;
         $mon++;
         $mon = "0$mon" unless $mon > 9;

# Logfiel-Eintrag
        my $fh = IO::File->new(">> /home/tk/logs/socket17500.log");
        $fh->print("$mday.$mon.$year $hour:$min:$sec  $buf - $client_ipnum\n");

externer programmstart -> `/home/tk/Documents/scripts/perl-networking/socketmsg.pl $buf $client_ipnum

#                                                                  "$mday.$mon.$year $hour:$min:$sec"`;

# Nachricht auf den Bildschirm
       Nachricht($buf,$client_ipnum,"$mday.$mon.$year $hour:$min:$sec");
    }
}

sub Nachricht
{
  my $n = shift;
  my $ip = shift;
  my $txt = shift;
  my $fenster = MainWindow->new('-bg' => 'red');
  $fenster->Label("-text" => "$txt\n\n$n   $ip ",
                  '-bg' => 'red' ,
                  '-font' => '-adobe-helvetica-bold-r-normal--20-140-75-75-p-82-iso8859-1')->pack();
  MainLoop;
}

Auch wenn ich jetzt die sub Nachricht() weg lasse und statt dessen mit Backticks versuche, ein externes Programm zu starten (siehe Quelltext) ist das ergebnis das Gleiche.

Wie kann ich die nachricht auf dem BS ausgeben und dort stehen lassen  trotzdem können weiter Fenster "aufpoppen"  und die Logfile-Einträge erfolgen korrekt.

Problem verstanden?
;-)

Bye
Timothy

P.S. dies ist nur ein Prototyp. Bitte nicht auf Eleganz oder Stil achten. Nur auf das Problem ;-) konzentrieren

--
Zwei Dinge im Leben kannst du nicht zurück holen. Den Pfeil, den du verschossen. Und das Wort, das du gesprochen.
(alte indianische Weisheit)
  1. Hi folks

    wahrscheinlich läuft das irgendwie auf "forking" hinaus - denke ich mal.
    Da muss ich mich aber erst einlesen

    Fakt ist wohl, dass immer gewartet wird, das Mainloop() beendet, also dass Fenster geschlossen wird, bis es weiter geht.

    Na, vielleicht hat ja noch jemand eine Idee.

    Bye
    Timothy

    --
    Zwei Dinge im Leben kannst du nicht zurück holen. Den Pfeil, den du verschossen. Und das Wort, das du gesprochen.
    (alte indianische Weisheit)
    1. Hi folks

      ich habe eine (vorläufige) Lösung gefunden.

      Interessiert?

      Okay:

      "fork" war schon die richtige Idee. In Verbindung mit "exec" und Installation eines passenden Signalhandlers (wegen Zombie-Prozessen) bringt die Lösung:

      <snippet>
      .

      $SIG{CHLD} = sub {wait();} ;
      .
      .
      .
      .unless (fork)
      {
           exec(" [ Programmaufwruf]");
      }
      </snippet>

      Dies genügt (vorerst) meinen Asprüchen.
      Ihr braucht Euch also keine Gedanken mehr zu machen.
      Einen schönen 4.advent noch

      Bye
      Timothy

      1. Hi folks

        das war's noch nicht. Habe ich alle PopUps geschlossen, ist auch der Hintergrundprozess beendet :-(

        Da muss ich wohl noch a bisserl weiter suchen.

        Bye
        Timothy

        --
        Zwei Dinge im Leben kannst du nicht zurück holen. Den Pfeil, den du verschossen. Und das Wort, das du gesprochen.
        (alte indianische Weisheit)
  2. Hi folks,

    ich möchte Euch ja nicht langweilen, aber vielleicht interessiert es ja doch jemanden.

    Also: "fork" ist richtig. Aber nicht mit "exec" !!!

    <snippet>

    my $fh = IO::File->new(">> /home/tk/logs/socket17500.log");
         $fh->print("$mday.$mon.$year $hour:$min:$sec  $buf - $client_ipnum\n");

    my $child = fork();
     if ($child == 0)
     {
         Nachricht($buf,$client_ipnum,"$mday.$mon.$year $hour:$min:$sec");
     };

    </snippet>

    That's all (mehr oder weniger).

    Der Parentprozess "lauscht" weiter, derweil das "Kind" das PopUp-Fenster zeigt.
    Ins Logfile wurde vor "fork" geschrieben.
    Jetzt (endlich) läuft es, so, wie ich es mir vorstelle.

    Bye
    Timothy

    --
    Zwei Dinge im Leben kannst du nicht zurück holen. Den Pfeil, den du verschossen. Und das Wort, das du gesprochen.
    (alte indianische Weisheit)