Hallo marv,
[quote=Guest,27.04.2007, 16:07]Aber setzt vorraus das ich die LÄNGE kenne...[/quote]
also ich habe mich beim Datenaustausch zwischen Client-Server für
das Konstrukt
IO::Socket::SSL,
Storable,
Safe,
read(),
pack() und
unpack() entschieden.
Mit Storable kann man Perlstrukturen serialisieren, was andere Scripts
mit Safe und Storable wieder zusammen setzen können. Mit pack() und
unpack() werden die Daten gepackt und entpackt. So weiß man auch,
wieviel Bytes gesendet wurden und kann das recht gut kontrollieren.
Hier ein Beispiel, wie man Daten versenden könnte:
use Storable qw(nfreeze);
# Wir wollen einen Hash senden
my $data = { foo => 1, bar => 2 };
# Die Daten werden mit Storable::nfreeze serialisiert
$data = nfreeze($data);
# Dann werden die Daten gepackt
$packet = pack("N/a*", $data);
# und zu guter letzt an den Client gesendet
print $socket $packet or die $!;
Als nächstes ein Beispiel, wie man die Daten verarbeiten kann, die
vom Client oder Server gesendet wurden:
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
use Storable qw(thaw);
use Safe;
# Storable nutzt Eval, dass wollen wir aber aus Sicherheitsgruenden
# nicht, deshalb sind wir mal so frech und ersetzen es einfach
# durch Safe::reval :-)
my $safe = new Safe;
$safe->permit(qw(:default require));
{ # 'once' scope
no warnings 'once';
$Storable::Deparse = 1;
$Storable::Eval = sub { $safe->reval($_[0]) };
}
# Es duerfen maximal 512 KB vom Server gesendet werden. Diesen Wert kann
# man natuerlich beliebig setzen.
my $maxbyt = 522488;
my ($buffer, $length, $bytes);
# Als erstes lesen wir 4 bytes aus dem Buffer. Diese 4 Bytes werden
# mit unpack entpackt, damit wir wissen, wieviel Bytes noch gesendet
# werden.
$bytes = read($socket, $buffer, 4);
die "read only $bytes/4 bytes from buffer" unless $bytes == 4;
$length = unpack("N", $buffer);
# 512 kilobytes ist das aboslute Maximum, was uns der Server/Client senden darf
die "the maximum size of bytes exceeded: $length" if $length > $maxbyt;
die "no data in buffer" unless $length;
# Jetzt lesen wir den Rest vom Socket in einer Schleife... der Grund fuer
# die Schleife ist, dass sich im Buffer maximal 16384 Bytes befinden
# koennen. Wenn mehr als 512 KB gesendet werden, brechen wir ab.
# Notiz: wenn weniger als 16384 Bytes im Buffer liegen, dann wird
# der Rest gelesen. In $bts stehen immer genau soviele Bytes
# drin, wie tatsächlich von read() gelesen wurde.
$buffer = '';
$bytes = 0;
while (my $bts = read($socket, my $buf, 16384)) {
$bytes += $bts; # Anzahl der bisher gelesenen Bytes
$buffer .= $buf; # Stück für Stück zusammen setzen
last if $bytes == $length;
# Hier wird geprueft, dass der Buffer keinesfalls groesser als
# 512 KB an Daten enthaelt.
die "the maximum size of bytes is overtaken" if $bytes > $maxbyt;
}
# Falls read() nichts mehr zurückgibt und die Schleife verlassen wird,
# ist es gut möglich, dass nicht alle Daten gelesen wurden.
die "read only $bytes/$length bytes from client" unless $bytes == $length;
# Die Daten werden mit thaw() rekonstruiert.
my $data = thaw($buffer) or die "unable to rebuild data ($!)";
Das sind alles ein Paar angepasste Codestückchen von mir selber.
Codefehler seien mir vergeben... aber an sich ist es nicht schlecht.
Ich habe auch mal vor einiger Zeit einen Bugreport eröffnet, weil ich
ein paar Probleme hatte. Da wird das gesamte Konstrukt vom Autor
von
IO::Socket::SSL kurz angeschnitten. Siehe hier:
rt.cpan.org ... id=23419
Gruss,
opi\n\n
<!--EDIT|opi|1177878163-->
What is a good module? That's hard to say.
What is good code? That's also hard to say.
One man's Thing of Beauty is another's man's Evil Hack.