Forum Programmation.perl Fermer proprement un socket

Posté par  .
Étiquettes : aucune
0
21
sept.
2006
Salut,

Je n'arrive pas à fermer correctement mon socket et ça commence à me souler...

Quand je sors du script en lui balançant "exit" le prog se termine normalement mais quand je le relance juste derrière j'ai une erreur à l'accrochage du socket : Adresse déjà utilisée...

Au bout d'une minute l'adresse est libérée et je peux réutiliser le port.

Qu'est-ce que j'oublie ?

# numero de port utilisé par le serveur
$port = 5123;
# protocole mis en jeu : TCP
$protocole = getprotobyname('tcp');
# creation du socket en écoute sur le port 5123
socket(ACCES_SERVEUR,AF_INET,SOCK_STREAM,$protocole) ||
die("Ouverture de socket: $!");
$TSAP_serveur = pack('SnA4x8', AF_INET, $port, INADDR_ANY);
bind(ACCES_SERVEUR,$TSAP_serveur) || die("Accrochage socket: $!");
listen(ACCES_SERVEUR, SOMAXCONN) || die("Ecoute socket: $!");


# on attend les connexions des clients...
$maSocket = accept(CLIENT, ACCES_SERVEUR);
while ($ligne = ){
@ordre = split(/\|/, $ligne);
for($i=0;$i<=$#ordre;$i++){
#Supprime les retour a la ligne en fin ligne
$ordre[$i]=~ s/\r\n//g;
#print $ordre[$i]."\t ".$sortie." \n";
}

print "\n***$ordre[0]***\n";

if($ordre[0] eq "exit"){
close(CLIENT);
close(ACCES_SERVEUR);
exit 1;
}
}


Merci :)
  • # perldoc -f shutdown

    Posté par  . Évalué à 3.

    Salut,

    J'ai rencontré ce problème également en C, je suis tombé sur la fonction shutdown.


    shutdown SOCKET,HOW
    Shuts down a socket connection in the manner indicated by HOW,
    which has the same interpretation as in the system call of the
    same name.

    shutdown(SOCKET, 0); # I/we have stopped reading data
    shutdown(SOCKET, 1); # I/we have stopped writing data
    shutdown(SOCKET, 2); # I/we have stopped using this socket

    This is useful with sockets when you want to tell the other
    side you're done writing but not done reading, or vice versa.
    It's also a more insistent form of close because it also dis-
    ables the file descriptor in any forked copies in other pro-
    cesses.
  • # C'est une feature, pas un bug

    Posté par  . Évalué à 6.

    La RFC décrivant TCP précise qu'apres la fermeture d'une socket, elle doit rester "inutilisable" pendant un certain temps (typiquement le round-trip time maxi défini pour une communication TCP), pour éviter qu'à une réouverture avec les mêmes ports, on se récupère des bouts de paquets de la connexion précédente qui étaient en transit dans les méandres d'internet.

    Apres avoir terminé une socket, regarde avec la commande "netstat -ap --ip" la liste des sockets existantes dans le système: celles qui sont fermées sont par exemple dans un état "TIME_WAIT".

    Pour forcer le bind d'une socket à l'identique avant expiration du délai, on peut fournir l'option de socket SO_REUSEADDR.
    En C on ferait setsockopt(s,SOL_SOCKET,SO_REUSEADDR, ...) (man setsockopt, man 7 socket) ; en perl il doit y avoir l'équivalent.
    • [^] # Re: C'est une feature, pas un bug

      Posté par  . Évalué à 2.

      Salut,

      J'avais déjà testé le "setsockopt" mais je n'avais pas réussi à le faire fonctionner. Et bien cette fois ci ça y est.
      Merci bien...

      Le shutdown ne résoud pas le problème. Voilà le code d'ouverture du socket qui va bien :)

      [code]
      socket(ACCES_SERVEUR,AF_INET,SOCK_STREAM,$protocole) || die("Ouverture de socket: $!");
      $TSAP_serveur = pack('SnA4x8', AF_INET, $port, INADDR_ANY);
      setsockopt(ACCES_SERVEUR, SOL_SOCKET, SO_REUSEADDR,1) || die "setsockopt() failed: $!\n";
      bind(ACCES_SERVEUR,$TSAP_serveur) || die("Accrochage socket: $!");
      listen(ACCES_SERVEUR, SOMAXCONN) || die("Ecoute socket: $!");
      [/code]

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n’en sommes pas responsables.