Schrift
[thread]4294[/thread]

TCP Client - Socket lesen und schliessen (Seite 3)

Leser: 1


<< |< 1 2 3 >| >> 30 Einträge, 3 Seiten
steffenw
 2004-09-04 23:32
#37547 #37547
User since
2003-08-15
692 Artikel
BenutzerIn
[Homepage] [default_avatar]
Hm, das weiß ich auch nicht. Bei mir stehen da immer Werte wie 512, 1024 oder 4096 drin. Wenn nur wenige Bytes kommen klappts trotzdem. Vielleicht ist 1 etwas besonderes, ich weiß es nicht. Wenn ich danach Byteweise verarbeiten will, dann schneide ich mit
Code: (dl )
my $byte = substr $buffer, 0, 1, '';
Stück für Stück vorn ab.
$SIG{USER} = sub {love 'Perl' or die};
Reinhard
 2004-09-06 18:45
#37548 #37548
User since
2004-08-18
16 Artikel
BenutzerIn
[default_avatar]
Hi steffenw, snarf etc...
das Program lief heute den ganzen Tag ohne Probleme.
Sieht sehr vernünftig aus.
Ich denke ich kann das Problem hiermit als gelöst melden.

Nochmals vielen Dank an Alle.
Reinhard
betterworld
 2004-08-18 19:16
#37549 #37549
User since
2003-08-21
2613 Artikel
ModeratorIn

user image
Bei mir funktioniert es. Aber:
(1) Beim oeffnen der $binFile solltest Du eine Fehlerabfrage einbauen. Vielleicht ist der Fehler einfach, dass die Datei nicht gefunden wird und daher nichts an den Server geschickt wird.
(2) Soweit ich weiss, muss autoflush noch das Argument 1 fuer "an" bekommen. Allerdings, laut man IO::Socket::INET:
Quote
As of VERSION 1.18 all IO::Socket objects have autoflush turned on
by default. This was not the case with earlier releases.
snarf
 2004-08-19 11:39
#37550 #37550
User since
2003-08-14
77 Artikel
BenutzerIn
[default_avatar]
Hallo Reinhard,

... hm ... ist das jetzt zu offensichtlich oder steh ich auf dem Schlauch?

Dein PHP-Script schickt das File an den Server und liest dann genau einmal vom Socket (max. 1024 Byte). Danach wird das Socket einfach geschlossen, d.h. es sieht so aus als würde Dein Server einen Verbindungsabbau von Seiten des Clients erwarten.

Dein Perlscript hingegen versucht in einer Schleife soviele 1 Byte "Blöcke" zu lesen bis nichts mehr kommt. Das Problem ist jedoch: solange das Socket offen ist, bricht ein read nicht ab - auch nicht, wenn zur Zeit noch nichts zum lesen ansteht!
Soll heißen ... der Client liest die komplette Antwort des Servers ein und wartet dann einfach, was wohl noch kommen mag (und wenn's auch hundert Jahre dauert).

Daher -> Nur einmal (max) 1024 Byte vom Socket lesen (also genau wie in Deinem PHP Script) und dann einfach das Socket schließen. Jedenfalls ist das die Funktionalität Deines PHP-Scriptes.

Es befinden sich somit (max.) 1024 Byte der Serverantwort in $Status und warten darauf, von Dir interpretiert zu werden.

Gruß, Dirk
steffenw
 2004-08-20 01:50
#37551 #37551
User since
2003-08-15
692 Artikel
BenutzerIn
[Homepage] [default_avatar]
... genau, oder Du schreibst $socket->blocking(0) und dann hängst Du auch nie.
$SIG{USER} = sub {love 'Perl' or die};
steffenw
 2004-08-21 00:47
#37552 #37552
User since
2003-08-15
692 Artikel
BenutzerIn
[Homepage] [default_avatar]
Ja stimmt, beim Senden hat man oft nicht die Probleme. Das sind dann schon eher die Extremfälle.

Beim Empfang bekommst Du die Bytes in den von Dir angegebenen Scalar und die length-Funktion sagt Dir, wie viele Bytes drin sind.

Ein Denkfehler ist manchmal, daß man erwartet, daß beim Empfang die angeforderten Bytes mit einem Mal kommen. Wenn das Paket zu groß wird, wird es aufgeteilt. Du forderst nur 1 Byte an, da kann das also nicht passieren, hopp oder top also.

Du hast bei Select bei der can_read-Methode keinen Timeout angegeben, also wird can_read blockieren, bis die Antwort kommt. Also macht es keinen Sinn, die Länge der Bytes zu testen. Wenn can_read zurückkommt, Du hast Select nur 1 Handle zugewiesen, ist das Byte auch da.

Übrigens funktioniert unter Windows IO::Select vorzüglich, da gibt es eher mal Probleme mit fork. Nur darf man bei Windows Select nicht auf Nicht-Socket-Handles anwenden, wie z.B. STDIN, ... .\n\n

<!--EDIT|steffenw|1093034954-->
$SIG{USER} = sub {love 'Perl' or die};
snarf
 2004-08-24 12:37
#37553 #37553
User since
2003-08-14
77 Artikel
BenutzerIn
[default_avatar]
Hallo Reinhard,

... sorry wenn ich mich bislang nicht weiter geäußert habe - war unverhofft untewergs.

AFAIK ist Dein Verständnis von select korrekt, soll heißen dass select nur grundsätzlich überprüft, ob von einem Socket gelesen werden kann (oder ob es sonst irgendwie geblockt wird).

Da scheinbar Dein Server den Socket nicht eigenständig schließt (bzw. dies wohl vom Client erwartet), bleibst Du natürlich hängen .... von einem offenen Socket kann man immer lesen (nur ob da auch was ansteht, ist ja bekanntlich fraglich).

Small workaround:
- vor der while-Schleife einmal die Systemzeit als Epoch erfragen
- innerhalb der Schleife eine Abfrage, ob eine bestimmte Zeit vergangen ist (d.h. Du z.B. seit ca. 30 Sekunden die Schleife durchläufst)
- if so: mit last aus der while-Schleife raus, Socket schließen, fertig.

Dieser Workaround bietet Dir natürlich keine Möglichkeit, nach dem Verbleib der "restlichen" Bytes zu forschen ... aber immerhin kannst Du Dein Skript mehr oder minder sauber beenden.

Gruss, Dirk
steffenw
 2004-08-24 22:25
#37554 #37554
User since
2003-08-15
692 Artikel
BenutzerIn
[Homepage] [default_avatar]
Die "can_read"-Methode gibt Dir alle Handles zurück, von denen Du lesen kannst, Du also beim Lesen nie blockieren wirst. Das ist ja der Sinn von "IO::Select".

Wenn der Puffer leer ist blockiert (endet nicht) can_read, weil Du keinen Timeout angegeben hast. Die while-Schleife endet nicht, kan garnicht, weil die Bedingung überhaupt nicht mehr geprüft wird!

Du kommst nur aus der while-Schleife, wenn die Gegenseite ein EOF sendet. Dann blockiert can_read auch nicht. "can_read" tut dann so, als wenn Du lesen könntest. Wenn Du aber liest ist die Anzahl der gelesenen Bytes genau 0, das ist Dein Zeichen. Ein EOF sendest Du von der Gegenseite, indem Du "shutdown($socket, 1)" ausführst. Oder war es nicht 1 sondern 2, lies mal in der Doku von "IO:Socket", das eine schließt die Empfangsseite, das andere die Sendeseite.

Wie schon gesagt, wie viele Bytes wirklich ankommen, ist der Rückgabeparameter von "read".

Alles was Du brauchst, gibt Dir "IO::Socket" an die Hand, vergiß so etwas wie Header lesen.\n\n

<!--EDIT|steffenw|1093372180-->
$SIG{USER} = sub {love 'Perl' or die};
Reinhard
 2004-08-26 22:46
#37555 #37555
User since
2004-08-18
16 Artikel
BenutzerIn
[default_avatar]
Hallo Dirk,
das mit der Systemzeit funktioniert leider nicht, da die Schleife nicht als ganzen immer wieder durchlaufen wird, sondern im ->recv hängen bleibt. Ich habe den Workaround
wie von steffenw mit dem ich wohl leben muss.

Danke nochmals für Deine Hilfe.
Reinhard
Reinhard
 2004-09-04 20:35
#37556 #37556
User since
2004-08-18
16 Artikel
BenutzerIn
[default_avatar]
Hallo,
wegen Verlängerung der Verlängerung bin ich erst jetzt wieder online.
steffenw, dein code funktioniert mit einer Aussnahme,
wenn maxPacket = 1 ist, bleibe ich hängen. Ich habe natürlich
immer nur mit 1 getestet - das Problem ist also keines mehr, da ich mindestens 10 Byte bekomme.

Besten Dank nochmal
Reinhard
<< |< 1 2 3 >| >> 30 Einträge, 3 Seiten



View all threads created 2004-08-18 19:50.