[Perl] Utilisation correcte de timeout_call

Utilisation correcte de timeout_call [Perl] - Perl - Programmation

Marsh Posté le 20-09-2013 à 17:43:41    

Salut,
 
C'est vendredi, et je suis bloqué sur un truc probablement assez trivial.
 
J'essaie d'utiliser Sys::SigAction pour mettre en place des timeouts corrects dans un programme utilisant des sockets. Le timeout "de base" pose problème sur certains LAN ou le firewall droppe les paquets sans informer la machine source, ce qui fait bloquer le programme.
 
Ce qui me pose souci a priori, c'est de passer proprement ma socket à la routine définie dans timeout_call
 
La boucle while est placée dans une routine, la variable $sock est locale et non globale.
 

Code :
  1. use constant SOCKET_TIMEOUT => 5;
  2. use constant SLEEP_TIME => 5;
  3. use constant MAX_SEND_RETRY => 3;
  4. ...
  5. while ( $retry++ <= MAX_SEND_RETRY)
  6. {
  7. $sock = IO::Socket::INET->new(
  8.      PeerAddr => $cl_address,
  9.      PeerPort => $port,
  10.      Proto => "tcp",
  11.      Timeout => SOCKET_TIMEOUT) or do
  12.    {
  13.     sleep SLEEP_TIME;
  14.     next;
  15.    };
  16. timeout_call (SOCKET_TIMEOUT,sub { my $sock = shift ; $sock->send($data_to_send . EOL) ;}, $sock) or do
  17.    {
  18.     sleep SLEEP_TIME;
  19.     next;
  20.    };
  21. $alarm_sent=1;
  22. $sock->close();
  23. }


Message édité par ccp6128 le 20-09-2013 à 17:46:42
Reply

Marsh Posté le 20-09-2013 à 17:43:41   

Reply

Marsh Posté le 20-09-2013 à 21:48:26    

Tu avais lu ces posts: http://www.perlmonks.org/?node_id=732970 ??
Je tenterais d'adapter la méthode commençant par: the final way is to use select, which may seem to be hard work,  
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 20-09-2013 à 22:31:18    

Ah, j'étais passé sur cette page à l'époque ou je cherchais la solution avec SO_RCVTIMEO et SO_SNDTIMEO (abandonnée car pas trop portable).
 
J'avais pas trop remarqué la solution avec select, j'avais lu trop vite probablement.
 
Je mets ça de côté pour recommencer à bosser dessus lundi.
 
Encore une fois, merci.

Reply

Marsh Posté le 23-09-2013 à 15:54:24    

Bon, a priori j'ai un truc qui marche avec Select, sauf truc que j'aurais loupé :
 

Code :
  1. while ( $retry++ <= MAX_SEND_RETRY ) {
  2.         $sock = IO::Socket::INET->new(
  3.             PeerAddr => $cl_address,
  4.             PeerPort => $port,
  5.             Proto    => "tcp",
  6.             Blocking => 0,
  7.             Timeout  => SOCKET_TIMEOUT
  8.           )
  9.           or do {
  10.             sleep SLEEP_TIME;
  11.             next;
  12.           };
  13.         $select = IO::Select->new($sock);
  14.         if ( $select->can_write(SOCKET_TIMEOUT) ) {
  15.             $rc = $sock->send( $data_to_send . EOL );
  16.             if (defined($rc)) {
  17.                   $alarm_sent = 1;
  18.                     $sock->close();
  19.                     last;
  20.             };
  21.         }
  22.     }

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed