Thread fork() & Variablen mitübernehmen (32 answers)
Opened by Sascha2018 at 2017-08-09 07:50

Sascha2018
 2017-08-12 16:34
#187221 #187221
User since
2017-08-05
51 Artikel
BenutzerIn
[default_avatar]
Guten Abend.

Nach stundenlangen rumprobieren und gefühlsmässig einer Ewigkeit,
habe ich es glaube ich geschafft.
Das Ganze muss ich nur noch irgendwie in meinen Servercode implementieren und hoffe es klappt dann.
Das Script welches ich nun poste, hat einen kleinen Haken.
Wenn ein Client den Browser schliesst, werden mehrere Verbindungen ( aufsteigend ) angezeigt.
Das möchte ich eigentlich nicht. Also muss man wohl irgendwie herausbekommen ob ein Client noch verbunden ist.

Über http://127.0.0.1/?sid=12 ruft man die Seite auf

Und über http://127.0.0.1/?printoall=1 sendet man Nachrichten. ( Natürlich kann man es auch anders umprogrammieren.

Hier mein Code. Viel Spaß damit:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#!/usr/bin/perl

use strict;
use warnings;
use feature 'state';

no strict 'refs';

use IO::Socket;
use IO::Select;
use Parallel::ForkManager;

my $die = 0;
my %lkup;
$|=1;

sub _uid {
state $uid = 0;
$uid = 1 if ++$uid > 2e9;
$uid;
}


my %clients = ();
my $select = IO::Select->new;

my $server = IO::Socket::INET->new(
LocalHost => '127.0.0.1',
LocalPort => 2222,
Proto => 'tcp',
Listen => 10000,
Reuse => 1,
) or die "Sock Error: $!\n";

my $pm = Parallel::ForkManager->new(500);
$pm->set_waitpid_blocking_sleep(0);

$pm->run_on_finish( sub {
my ($pid,$exitcode,$ident,$exitsignal,$coredump,$get) = @_;
$clients{$ident}->{ident} = $ident;
$clients{$ident}->{ip} = $get->{ip};
$clients{$ident}->{socket} = delete $lkup{$ident};
my $killsock = $get->{killing} || 0;
my $sock = $clients{$ident}->{socket};
if($killsock){
delete $clients{$ident};
$select->remove($sock);
}
});

$server->autoflush(1);
$select->add($server);

while (1) {
foreach my $key ($select->can_read()) { # foreach
if ($key eq $server) { # if $bay eq $server
next if $key eq "";

my $bay = $server->accept or next;
my $ip = $bay->peerhost();
our $ident = _uid();

$lkup{$ident} = $bay;
$select->add($bay);
my $buffer = <$bay>;
$pm->start($ident) and next;
my $killing = 0;

if( defined $buffer && $buffer =~ m/^GET\s\/\?sid=12\sHTTP\/1\.1\s/ ){
print "$buffer";
sendHeader($bay);
print "OK";
for( 1 .. 30 ){ # Firefox and other browsers
$bay->syswrite("<!-- //--><!-- //--><!-- //--><!-- //--><!-- //-->\n\n");
}
my $html=<<"EOT";
<html>
<head>
<title>hallo</title>
</head>
<body style='background-color: darkblue; color: #FFFFFF'>
hello world
</body>
</html>
EOT

$bay->syswrite($html);
}elsif( defined $buffer && $buffer =~ m/^GET\s\/\?printoall=1\sHTTP\/1\.1\s/ ){
foreach my $client( keys %clients ){
print "$buffer";
my $socket = $clients{$client}->{socket};
$socket->syswrite("The sun is shining\n");
print "Conntected: \n" . keys %clients;

}
$killing = 1;
}

$pm->finish(0, { ip => $ip, killing => $killing });
}
}

$pm->wait_all_children;
}

sub sendHeader {
my $client = shift;
if( defined $client ) {
my $header =<<"EOT";
HTTP/1.1 200 OK
Content-type: text/html\n\n
EOT
$client->syswrite($header);
}
}


Ich gebe keine Garantie ...
Falls ich etwas falsch programmiert habe, lasst es mich wissen.

Danke
Sascha

View full thread fork() & Variablen mitübernehmen