Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]11980[/thread]

Socket receive-Frage

Leser: 6


<< |< 1 2 3 4 >| >> 36 Einträge, 4 Seiten
H3llGhost
 2008-06-05 17:32
#110777 #110777
User since
2007-10-14
60 Artikel
BenutzerIn
[default_avatar]
Hallo Leute,

ich habe folgenden Code:

Code (perl): (dl )
1
2
3
4
5
6
7
                if(IO::Select->new($s_socket)->can_read(10)) {  # 2 second timeout
                  $s_socket->recv($s_output, 1024);
                  $timeout = 0;
                  print $s_output;
                } else {
                  $timeout++;
                }


Und dieser Code empfängt vom Server einen Datenstring, nur dieser Datenstring ist extrem lang.
Ich weiß, dass man mit der Zahl 1024 die Länge verändern kann die empfangen wird.
Nur der String ist länger als 1024 und wächst auch, denn es werden Daten übertragen, welche expotentiell auf dem Server anwachsen.
Sprich heute sind es 50 Namen und morgen sind es 60 Namen, usw.
Nun möchte ich das gerne so anpassen, dass der so lange empfängt bis nichts mehr kommt.

Habt ihr eine Idee wie ich das am Besten realisieren kann?
GwenDragon
 2008-06-05 17:41
#110778 #110778
User since
2005-01-17
14548 Artikel
Admin1
[Homepage]
user image
recv liefert die Anzahl der gelesenen bytes, d.h. 0 wenn nichts mehr kommt.

Packe es in eine Schleife:
Code: (dl )
1
2
3
4
5
my $buffer = '';
while (my $rc = $s_socket->recv($s_output, 1024) ) {
$buffer .= $s_output;
}
# und dann weitere Verarbeitung
die Drachin, Gwendolyn


Unterschiedliche Perl-Versionen auf Windows (fast wie perlbrew) • Meine Perl-Artikel

H3llGhost
 2008-06-05 17:58
#110780 #110780
User since
2007-10-14
60 Artikel
BenutzerIn
[default_avatar]
Habe es nun so angewandt:

Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
        while ($timeout % 60 == 0)
        {
                print "hier";
                if(IO::Select->new($s_socket)->can_read(2)) {  # 2 second timeout
                        while (my $rc = $s_socket->recv($s_output, 1024) ) {
                        $buffer .= $s_output;
                        }
                        print $buffer;
                        $timeout = 0;
                  # $s_socket->recv($s_output, 1024);
                  # $timeout = 0;
                  # print $s_output;
                } else {
                  $timeout++;
                }       
                print $timeout;
        }


Geht aber leider nicht ...
Ich habe da wohl eine Sache reingepackt was nicht sinnvoll ist oder?
Ich habe auch noch nicht ganz den Sinn der $timeout-Schleife verstanden.
moritz
 2008-06-05 18:03
#110781 #110781
User since
2007-05-11
923 Artikel
HausmeisterIn
[Homepage]
user image
Du benutzt das neu erstellte Socket-Objekt überhaupt nicht.

Code (perl): (dl )
1
2
my $s_socket = IO::Socket->new(...);
# jetzt mit $s_socket weiter arbeiten
GwenDragon
 2008-06-05 18:50
#110784 #110784
User since
2005-01-17
14548 Artikel
Admin1
[Homepage]
user image
Ach je, das kommt davon, wenn sich eine zu sehr auf die Pufferung konzentiert und nicht sieht, dass das Socket-Objekt auch noch falsch initialisiert ist.
Aber wir sind hier ja mehrere Leute ;)
die Drachin, Gwendolyn


Unterschiedliche Perl-Versionen auf Windows (fast wie perlbrew) • Meine Perl-Artikel

H3llGhost
 2008-06-06 00:26
#110800 #110800
User since
2007-10-14
60 Artikel
BenutzerIn
[default_avatar]
Also so möchte es nicht funktionieren ...

Code (perl): (dl )
my $s_socket = IO::Select->new($s_socket);


Habe gerade einen Fehler meinerseits gesehen ...
Ich habe Select statt Socket genohmen ...
Aber ich weiß gerade nicht wie ich den Port damit reinbringe ...

EDIT:
So habe ich das jetzt geregelt:

Code (perl): (dl )
1
2
3
4
$s_socket = IO::Socket::INET->new(
        Proto=>"udp",
        LocalAddr=>"$s_ip",
        LocalPort=>"$s_port");
H3llGhost
 2008-06-07 19:22
#110862 #110862
User since
2007-10-14
60 Artikel
BenutzerIn
[default_avatar]
Also mein Code sieht nun folgendermaßen aus:

Code (perl): (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
if ($s_ip) { $ip = $s_ip . ":"; } else { $ip = "port "; }

my $s_socket = IO::Socket::INET->new(
        Proto=>"udp",
        LocalAddr=>"$s_ip",
        LocalPort=>"$s_port"
) or die ("\nCan't setup UDP socket on $ip:$s_port $!\n");

print("Opening UDP listen socket on $ip$s_port ... ok\n");

        while ($timeout % 60 == 0)
        {
                print "hier";
                if(IO::Select->new($s_socket)->can_read(2)) {  # 2 second timeout
                        while (my $rc = $s_socket->recv($s_output, 1024) ) {
                        $buffer .= $s_output;
                        }
                        print $buffer;
                        $timeout = 0;
                  # $s_socket->recv($s_output, 1024);
                  # print $s_output;
                } else {
                  $timeout++;
                }       
                print $timeout;
      }


Doch leider funktioniert das nicht ...
Hat jemand eine Idee, wie warum das bei mir nicht geht ...
renee
 2008-06-07 19:30
#110866 #110866
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
H3llGhost+2008-06-07 17:22:00--
Doch leider funktioniert das nicht ...
Hat jemand eine Idee, wie warum das bei mir nicht geht ...


Das ist keine adäquate Fehlerbeschreibung! Was funktioniert, was funktioniert nicht? Gibt es eine Fehlermeldung? Kannst Du ein minimales Programm schreiben, das den Fehler reproduziert? usw...
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
H3llGhost
 2008-06-07 19:37
#110867 #110867
User since
2007-10-14
60 Artikel
BenutzerIn
[default_avatar]
Es kommt keine Fehlermeldung.
Es wird einmal hier ausgegeben und dann kommt 1.
Die 1 steht für das Timeout und dann ist Schluss.
Programm wird beendet ...
H3llGhost
 2008-06-07 19:54
#110868 #110868
User since
2007-10-14
60 Artikel
BenutzerIn
[default_avatar]
Dieser Code steht vor der while-Schleife:

Code (perl): (dl )
1
2
3
4
5
6
7
8
        $host_data = (gethostbyname($g_masterserver_address))[4];
        my $address        = join(".", unpack("C4", $host_data));
        my $port           = $g_masterserver_port;
        my $dest           = sockaddr_in($port, inet_aton($address));

        $msg = chr(0xff).chr(0xff)."Z".chr(0xff);
        $bytes = send($::s_socket, $msg, 0, $dest);
        print("$bytes to '$address:$port'");


Und hier noch den Code den ich von php versuche in Perl zu übertragen:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
      $socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
$packet = chr(255).chr(255)."Z".chr(255);
$bytes_sent = socket_sendto($socket, $packet, strlen($packet), 0, $host, $port);
echo "<b>".$bytes_sent."</b> bytes <b>OK</b></li>";
$recv_bytes = 0;
$buffer = "";
$timeout = 30;
$answer = "";
$packets = 0;
$read = array($socket);
while (socket_select($read, $write = NULL, $except = NULL, &$timeout) > 0) {
$recv_bytes += socket_recvfrom($socket, &$buffer, 2000, 0, &$host, &$port);
if (($buffer[0] == chr(255)) && ($buffer[1] == chr(255)) && ($buffer[2] == "Z") && ($buffer[3] == chr(255)) &&
($buffer[4] == "1") && ($buffer[5] == ".") && ($buffer[6] == "0") && ($buffer[7] == "0") && ($buffer[8] == chr(255))) {
$answer .= substr($buffer, 9, strlen($buffer));
}
$buffer = "";
$timeout = "1";
$packets++;
}
<< |< 1 2 3 4 >| >> 36 Einträge, 4 Seiten



View all threads created 2008-06-05 17:32.