Schrift
[thread]4294[/thread]

TCP Client - Socket lesen und schliessen

Leser: 1


<< |< 1 2 3 >| >> 30 Einträge, 3 Seiten
snarf
 2004-08-18 19:50
#37527 #37527
User since
2003-08-14
77 Artikel
BenutzerIn
[default_avatar]
Hallo Reinhard,

... an diesem ''@@/!!#" Tag sind sind "dumme" Fragen erlaubt:

a) bleibt er in der Schleife hängen mit einer endlos-ausgabe?
-> schade, keine Ahnung

b) bleibt er einfach nur stehen?
-> hast Du auch das Socket server-seitig geschlossen? Sonst wartet er nämlich einfach bis in die Ewigkeit auf das Ausführen seines Reads ...

By the way - ich denke mal das Du bei einem closed socket ein undef lesen würdest statt einer 0

Gruss, Dirk
snarf
 2004-08-20 00:31
#37528 #37528
User since
2003-08-14
77 Artikel
BenutzerIn
[default_avatar]
Hallo Reinhard,

na, dann lass doch einfach die zu lesende Bytezahl weg (sofern möglich, sitze gerade an einer "perllosen" Kiste und kann's nicht überprüfen).

Ansonsten einfach ein simpler read vom handle (a la $text = <SOCKET>)

Die von Dir gewünschte Funktionalität (1 Sekunde warten, dann schließen) mußt Du über den Umweg eines Signal-Handlers einbauen. Ich muss morgen mal sehen, ich habe da noch irgendwo ein snipplet liegen ...

Gruss, Dirk
steffenw
 2004-08-20 23:13
#37529 #37529
User since
2003-08-15
692 Artikel
BenutzerIn
[Homepage] [default_avatar]
Wenn Du Bytes sendest, bringt Dir send immer zurück, wie viele Bytes gesendet werden konnten. Im nonblocking-Modus können es auch 0 sein, sonst mindestens eins.

Du mußt Dir einen Ausgangspuffer aufbauen, in den Du die Bytes einträgst, die vom File kommen und dann die gesendeten Bytes vorn von diesem Puffer wieder abziehen.
Code: (dl )
1
2
3
4
5
6
my $outbuf = '';
while (read FileHandle, $buf, 28)
{ $outbuf .= $buf; # zum Senden anhängen
my $len = $socket->send($outbuf); # Sendeversuch - heißt, es muß nicht klappen
$len and substr $outbuf, 0, $len, ''; # vorn wieder abschneiden
}
Jetzt könnten noch Bytes in $outbuf sein, wenn diese nicht gesendet werden konnten. Entweder Du blockierst spätestens hier oder betrachtest das als Fehler.
$SIG{USER} = sub {love 'Perl' or die};
steffenw
 2004-08-22 14:07
#37530 #37530
User since
2003-08-15
692 Artikel
BenutzerIn
[Homepage] [default_avatar]
Wenn Du 1024 Zeichen empfangen willst und nur 512 in einem Paket sind, kommen die ersten 512 und mit dem 2. Paket hoffentlich die restlichen 512 oder eben ein weiterses Paket... . Du forderst eine maximale Länge an, nicht eine minimale. Das Select sagt Dir nur, daß es etwas zu lesen gibt und nicht wieviel, vollständig oder so etwas. Also sammle in der while-Schleife solange Daten, bis es 1024 sind oder Du einen Fehler entdeckst. Byteweise lesen ist unperformant. Wenn Du aus der while-Schleife nicht mehr rauskommst, sind die Daten auch nicht da, also lesbar. Such also dann weiter, wo die Daten gesendet werden.
$SIG{USER} = sub {love 'Perl' or die};
steffenw
 2004-08-25 23:41
#37531 #37531
User since
2003-08-15
692 Artikel
BenutzerIn
[Homepage] [default_avatar]
[quote=Reinhard,25.08.2004, 18:56]@steffenw->Warst Du nicht derjenige, der mir empfohlen hat nicht read zu nehmen ;-)

und bei der Beschreibung von recv ist diesbezgl. nichts zu finden[/quote]
Oh, Sche..., ich habe mich verschreiben, recv ist natürlich ok. Bei recv kannst auch nichts über die Länge finden. Zuerst liest Du mit "recv" die Bytes in den genau da angegebenen Scalar und danach prüfst Du mit "length($eben_dieser_Scalar)" wie lang eben dieser Scalar nun ist. Da kann 0 bis die maximale Länge, die Du mit "recv" angefordert hast herauskommen. 0 heißt im blocking-Modus, EOF von der Gegenseite erhalten.
$SIG{USER} = sub {love 'Perl' or die};
Reinhard
 2004-08-27 23:09
#37532 #37532
User since
2004-08-18
16 Artikel
BenutzerIn
[default_avatar]
Hallo steffenw,
danke für Dein Beispiel, aber das Ergebnis ist das gleiche. Ich bleibe hier $SocketHandle->recv($Status, $maxPacket) hängen. Der Timeout für select bringt hier nichts.

Danke
Reinhard

p.s. ich werde in ein verlängertes Wochenende gehen, also bis Mittwoch habt Ihr Ruhe vor mir ;-)
Gast Gast
 2004-08-18 19:08
#37533 #37533
Hallo,
ich versuche mich gerade daran, einen TCP Client zu schreiben. Funktioniert auch einigermassen, nur habe ich das Problem, dass ich aus der "Socket lesen" Schleife nicht mehr herauskomme. Was ich mache, eine Binärdatei einlesen und an den Server schicken und danach die Antwort des Servers darstellen, nur da bleibt das Programm in der Schleife hängen.

Habt Ihr vielleicht eine Idee wie ich das abfangen kann?

Danke
Reinhard

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
use strict;
use Config;
use IO::Socket::INET;

my $SocketHandle;
my $buf;
my $binFile  = "<e:/test.bin";
my $Status;

unless (@ARGV == 2) { die "Usage: GetStatus.pl remotehostname port" }

$SocketHandle = IO::Socket::INET->new(PeerAddr =>  $ARGV[0],
                                     PeerPort =>  $ARGV[1],
                                     Proto    =>  "tcp",
                                     Timeout  =>  10,
                                     Type     =>  SOCK_STREAM) or die "cannot connect: $!\n";
$SocketHandle->autoflush();

open(FileHandle, $binFile);
binmode(FileHandle);

while (read(FileHandle, $buf, 28))
{
   print $SocketHandle $buf;
}

$|=1;
while (read ($SocketHandle,$Status,1))
{
print($Status);
}

close FileHandle;
close $SocketHandle;
Reinhard
 2004-08-18 19:30
#37534 #37534
User since
2004-08-18
16 Artikel
BenutzerIn
[default_avatar]
Danke für deine Antwort.
Die Binärdatei kann gelesen und gesendet werden. Mein Problem liegt hier

Code: (dl )
1
2
3
4
while (read ($SocketHandle,$Status,1))
{
print($Status);
}


ich bekomme die Antwort vom Server, das read wird aber nicht beendet. Ich habe auch versucht
Code: (dl )
while (read ($SocketHandle,$Status,1) ne 0)

hilft leider auch nicht.

Danke
Reinhard
Reinhard
 2004-08-18 20:08
#37535 #37535
User since
2004-08-18
16 Artikel
BenutzerIn
[default_avatar]
Hallo Dirk,

dumme Fragen gibt es nicht :-)

a) bleibt er in der Schleife hängen mit einer endlos-ausgabe?
nein

b) bleibt er einfach nur stehen?
ja, ich habe aber leider keinen Zugriff auf den Server.

Die 0 ist bei read, oder? Ich bin relativ neu in perl, vielleicht habe ich da etwas falsch verstanden. Laut Doku soll nämlich read

Attempts to read LENGTH *characters* of data into variable
SCALAR from the specified FILEHANDLE. Returns the number of
characters actually read, 0 at end of file, or undef if there
was an error (in the latter case $! is also set).

Veilleicht sollte es != 0 und nicht ne 0 heissen. Bringt aber auch nichts.
Um nochmal auf den Server zurückzukommen, ich denke er reagiert richtig, da ich z.b. ein php skript habe, dass macht das was es soll - nur ich möchte, muss es mit perl realisieren, da ich auf meiner Maschine kein php installieren darf.

wenn es helfen sollte, hier das php skript
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
<?php
$SocketHandle = fsockopen ("localhost", 5727, $errno, $errstr, 2);
if (!$SocketHandle)
{
echo "$errstr ($errno)";
}
else
{
$FileName = "e:/test.bin";
   $FileHandle = fopen ($FileName, "r");
   if (!$FileHandle)
    {
echo "File not found";
    }
   else
    {
    $FileContent = fread ($FileHandle, filesize($FileName));
    fclose ($FileHandle);
    fputs ($SocketHandle, $FileContent);
    $Return = fread($SocketHandle, 1024);
echo trim(substr($Return,28));
    }
   fclose($SocketHandle);
}
?>


Danke
Reinhard
Reinhard
 2004-08-19 19:24
#37536 #37536
User since
2004-08-18
16 Artikel
BenutzerIn
[default_avatar]
Hallo Dirk,

ja, genau erkannt. Ich dachte zuerst, dass ich das php einfach nach perl umschreiben könnte. Leider verhält sich da perl ewas anders. Den wenn ich
Code: (dl )
1
2
    read ($SocketHandle,$Status,1024);
print($Status);

schreibe, bleibt es ebenfalls im read hängen. Ich habe schon viel im Web gesucht, aber keinen Ansatz zur Lösung gefunden.
Ich müsste etwas nach dem Motto "lese vom socket und wenn 1 Sekunde lang nichts mehr kommt, dann schliesse" finden.

Danke
Reinhard
<< |< 1 2 3 >| >> 30 Einträge, 3 Seiten



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