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

Wie mit blockierenden Funktionen umgehen?: Socket recv

Leser: 1


<< >> 9 Einträge, 1 Seite
HuberDe
 2006-12-18 12:07
#72592 #72592
User since
2006-10-26
15 Artikel
BenutzerIn
[default_avatar]
Hallo zusammen,

ich habe das Problem, dass ich unter Windows mit den Sockets arbeite. Nun habe ich von Zeit zu Zeit das Problem, dass ich von meinem Zielgerät keine Antwort mehr bekomme
und somit meine recv Funktion auf immer und ewig stehen bleibt, da die socket funktionen in Windows blockierend sind und sich das meines Wissens nach auch nicht ändern lässt. Daraufhin habe ich die Funktion in einen Thread ausgelagert, damit ich über verschiedene Prüfmethoden den Thread abschießen kann, wenn er eine zeit lang nicht antwortet und somit an der recv Funktion wartet. Dies habe ich mit einem Signalhandler versucht, musste jedoch festellen, dass die neuen Signalhandler nur noch greifen, wenn perl die aktuelle aufgabe abgearbeitet hat. Somit kann ich ihn mit einem Signal auch nicht aus der recv Funktion raus holen.

Weiß irgendjemand wie ich aus einer blockierenden Funktion dieser Art rauskomme?

Danke, Denis
renee
 2006-12-18 12:22
#72593 #72593
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Vielleicht hilft Dir dieser Wiki:Artikel weiter...
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/
HuberDe
 2006-12-18 12:58
#72594 #72594
User since
2006-10-26
15 Artikel
BenutzerIn
[default_avatar]
Hi Renee,

nur bedingt. Denn .... can_read kommt ja mit true zurück, sobald der socket offen ist. Meiner is ja aber immer offen, es kann nur sein, dass der Gegenpartner (Client) nicht antwortet, die Verbindung aber trotzdem besteht.\n\n

<!--EDIT|HuberDe|1166439932-->
nepos
 2006-12-18 13:59
#72595 #72595
User since
2005-08-17
1420 Artikel
BenutzerIn
[Homepage] [default_avatar]
Hm, wie machst du das mit dem Socket? In CPAN:IO::Socket kann man z.B. nen Timeout setzen.
HuberDe
 2006-12-18 14:47
#72596 #72596
User since
2006-10-26
15 Artikel
BenutzerIn
[default_avatar]
Ich benutze die socket::io::net. Das can_read funktioniert vlt. doch irgendwie. Muss ich mal n bissel damit rumspielen.

Danke mal.
Denis
betterworld
 2006-12-18 15:38
#72597 #72597
User since
2003-08-21
2613 Artikel
ModeratorIn

user image
[quote=HuberDe,18.12.2006, 11:58]Hi Renee,

nur bedingt. Denn .... can_read kommt ja mit true zurück, sobald der socket offen ist.[/quote]
Nein, es sollte erst zurueckkehren, wenn wirklich Lesestoff da ist.

Außerdem gibt es noch O_NONBLOCK (mehr dazu bei Google).
HuberDe
 2006-12-18 16:45
#72598 #72598
User since
2006-10-26
15 Artikel
BenutzerIn
[default_avatar]
@Betterwold,

nonblock funktioniert aber nur auf Unix systemen!?
sid burn
 2006-12-21 17:34
#72599 #72599
User since
2006-03-29
1520 Artikel
BenutzerIn

user image
[quote=HuberDe,18.Dec..2006, 15:45]@Betterwold,

nonblock funktioniert aber nur auf Unix systemen!?[/quote]
Wenn du select() benutzt dann brauchst du ja gar kein Non-block Modus.

Ansonsten sollte non-block auch auf Windows gehen. Generell sollte es sogar die einzige Portable Lösung sein zwischen Unix, Windows und MacOS (< 10).\n\n

<!--EDIT|sid burn|1166715565-->
Nicht mehr aktiv. Bei Kontakt: ICQ: 404181669 E-Mail: perl@david-raab.de
styx-cc
 2006-12-21 18:42
#72600 #72600
User since
2006-05-20
533 Artikel
BenutzerIn

user image
ja, sid_burn mit select gehts. Ich schreibe auch gerade einen Clienten und habe habe mich mit der Thematik befasst, mit IO::Select (auch mit select()) kannst du ein Timeoute setzen, nach dem die schleife ein mal "durchrutscht", ich poste mal den Code den ich da zusammen gebaut habe, ist allerdings noch absolute Testphase :)
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
my $SOCK;
sub main_connection {
my $text = shift;#prompt-msg
sleep(30) unless $FST;#provide serverflooding
$FST = 0;
print "$text\n";
$SOCK = shake_hands();
login();
#use select to have a non-blocking socket
my $sock = new IO::Select( $SOCK );
main_loop($sock);
} #sub main_connection

sub main_loop {
my $sock = shift;
my $died = 0;#check flag
while (1) {
#get data from socket, if there some
while ((my @ready = $sock->can_read(240))) {
for my $fh (@ready) {#checkout readable fhs
if($fh == $SOCK) {
my $input;
unless(sysread($SOCK,$input,2048)) { $died = 1 };
last if $died;
if($input) {
ping_check();
#in some cases we've more than one cmd in a line
#so we've to split them by \n, cause server seperates by \n
my @cmds = split /\n/, $input;
for my $line (@cmds) {
open_log() unless check_log("logs/$logfile");
start($line);
}
} else {
print "unknow socketerror...\n";#syswrite returns 1, but we haven't some input?
}
last;
}
}
last if $died;
}
last if $died;
ping_check() or last;
print "Nichts passiert!\n";
}
$sock = main_connection('Socketerror, trying to reconnect..');
main_loop($sock);
} #main_loop()

sub shake_hands {
my $host = 'www.example.com';
my $port = '0000';
#open socket to chatserver
my $socket = IO::Socket::INET->new(
PeerAddr => $host,
PeerPort => $port,
proto => 'tcp',
type => 'SOCK_STREAM',
Timeout => 20);
main_connection("No Network! Relogin..") unless $socket;
return $socket;
} #sub shake_hands

Vielleicht hilft das ja weiter,
wenn auf dem Socket 240 Sekunden lang ncihts passiert, gibt er einmal "Nichts passiert!" aus.
MfG

Edit: das laeuft auf Windows und unter Linux\n\n

<!--EDIT|styx-cc|1166719531-->
Pörl.
<< >> 9 Einträge, 1 Seite



View all threads created 2006-12-18 12:07.