IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Réseau/Web Python Discussion :

[Sockets] Erreur 98 "address already in use"


Sujet :

Réseau/Web Python

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 8
    Points : 4
    Points
    4
    Par défaut [Sockets] Erreur 98 "address already in use"
    Amis du net, Bonjour!

    J'ai dans le cadre de mes études, un petit programme à écrire qui est une approche aux notions de sockets etc.. et je dois simuler un mini "serveur" qui est lancé et est en attente de connexion. Je lance le serveur sur un premier terminal et me connecte via telnet sur un autre terminal au "serveur" (Le code est bien modeste je l'avoue mais je suis phase d'apprentisage xD)

    Le problème est que lorsque le client ferme ou le serveur ferme la connection, lorsque je veux relancer le programme serveur, j'ai l'erreur suivante socket.error: (98, 'Adress already in use')

    Je ne vois ou est le problème, pourtant le socket serveur est fermer correctement avec close ().

    Merci de m'éclairer, voilà le code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    #!usr/bin/env python
     
    import os, sys, socket, select
    host = ''
    port = 5000
    add = (host, port) 
     
    server = socket.socket (socket.AF_INET, socket.SOCK_STREAM) 
    server.bind (add)  
    server.listen (1) 
    input = [server]
    run = 1
     
     
     
    print "Serveur connecte avec succes depuis %s sur le port %d...\n" % (host, port)
     
    while run:
        read, write, error = select.select (input, [], [], 5) 
        for i in read:
            if i == server:
                raw_input ("Appuyez sur entree pour continuer...\n")
                client, (hostc, portc)  = server.accept () 
                input.append (client) 
                print "Client %s connecte avec succes depuis le port %d...\n" % (hostc, portc)
     
            else:  
                msg = i.recv(100) 
                test = "TEST"
                stop = "STOP"
                if (test.rstrip () in msg.rstrip ()):
                    os.write(1, "test reussi...\n")
                elif (msg.rstrip() == stop.rstrip()):
                    os.write (1, "Serveur arreter...BYE\n")
                    #i.close ()
                    #input.remove (i)
                    run = 0
                    #server.close () 
     
                else: 
                    print ("Aucun message...BYE")
                   # i.close ()
                    #input.remove (i)
                    run = 0
     
    server.close ()
    print "Server shutdown...BYE"

  2. #2
    Membre éprouvé
    Avatar de Antoine_935
    Profil pro
    Développeur web/mobile
    Inscrit en
    Juillet 2006
    Messages
    883
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur web/mobile

    Informations forums :
    Inscription : Juillet 2006
    Messages : 883
    Points : 1 066
    Points
    1 066
    Par défaut
    En général, un socket qui n'a pas été fermé correctement reste inutilisable quelque temps, et ça peut durer longtemps.

    Donc, si ton programme fait un raise non intercepté quelque part, tu es bon pour attendre que le socket se libère.

    Le plus simple et le plus propre, c'est de prendre toute ta boucle dans un try/finally.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    try:
        boucle()
    finally:
        fermer_socket()
    Je ne suis pas un expert en socket, loin de là, mais ne devrais-tu pas utiliser SocketServer plutôt ?

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 8
    Points : 4
    Points
    4
    Par défaut
    Bonjour et merci pour cette réponse rapide!

    Je ne connaissé pas le try/finally, merci pour cette info au passage mais malgré ça, le problème persiste, le socket ne se ferme toujours pas correctement apparement...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    #!usr/bin/env python
     
    import os, sys, socket, select
     
    #nb = 1
    #first = 1
    host = ''
    port = 5000
    add = (host, port) 
     
    server = socket.socket (socket.AF_INET, socket.SOCK_STREAM) #creation socket serveur
    server.bind (add) # on attribue au server une adresse et port d'ecoute 
    server.listen (1) # le server est actif et est attente ac queue max = 1
    input = [server]
    run = 1
     
     
    print "Serveur connecte avec succes depuis %s sur le port %d...\n" % (host, port)
     
    try:
        while run:
     
            read, write, error = select.select (input, [], [], 5) # on surveiller input (=server, stdin (clavier)), timeout 20
            for i in read:
                if i == server:
                    raw_input ("Appuyez sur entree pour continuer...\n")
                    client, (hostc, portc)  = server.accept () # s'il y'a demande de connexion, creation socket client
                    input.append (client) # on ajoute le socket client aux choses a surveiller
                    print "Client %s connecte avec succes depuis le port %d...\n" % (hostc, portc)
     
                else: # protocole test 
                    msg = i.recv(100) 
                    test = "TEST"
                    stop = "STOP"
                    if (test.rstrip () in msg.rstrip ()):
                        os.write(1, "test reussi...\n")
     
                    elif (msg.rstrip() == stop.rstrip()):
                        os.write (1, "Serveur arreter...BYE\n")
                        run = 0
     
                    else: 
                        print ("Aucun message...BYE")
                        run = 0
    finally:               
        server.close ()
        print "Server shutdown...BYE" 
    sys.exit (0)


    SocketServer? Eu sûrement mais je ne connais pas cette fonction, mais normalement je dois pouvoir le faire avec socket mais c'est quoi SocketServer?

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    271
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Décembre 2006
    Messages : 271
    Points : 329
    Points
    329
    Par défaut
    Tu peux utiliser SO_REUSEADDR :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    server = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
    server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    server.bind (add)
    # ... etc

  5. #5
    Membre éprouvé
    Avatar de Antoine_935
    Profil pro
    Développeur web/mobile
    Inscrit en
    Juillet 2006
    Messages
    883
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur web/mobile

    Informations forums :
    Inscription : Juillet 2006
    Messages : 883
    Points : 1 066
    Points
    1 066
    Par défaut
    Citation Envoyé par iReNu Voir le message
    Je ne connaissé pas le try/finally, merci pour cette info au passage mais malgré ça, le problème persiste, le socket ne se ferme toujours pas correctement apparement...
    J'ai un peu joué avec ton code (merci d'ailleurs, tu viens de m'apprendre à me servir de sockets). J'ai remarqué que le socket était bloqué seulement quand un des clients n'avait pas encore fermé sa connection, et ce même si le serveur est coupé.

    Et la solution de Tamiel semble bien fonctionner. Merci à lui

    Edit: Et pour répondre à ta question que je viens de voir, SocketServer est une classe qui facilite la création de serveurs réseaux.
    Enfin... faciliter... vu la simplicité de ton code je vois mal comment on pourrait faire mieux.
    La doc: http://docs.python.org/library/socketserver.html

  6. #6
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 8
    Points : 4
    Points
    4
    Par défaut
    En effet!

    Merci tamiel, ça a l'air de marcher nickel! Mais juste pour information, que fais cette ligne?

    Oui si j'ai bien compris il aurait fallu fermer le socket client et ensuite le serveur pour que ce soit quelque chose de plus correcte.

    Problème résolu!

  7. #7
    Membre éprouvé
    Avatar de Antoine_935
    Profil pro
    Développeur web/mobile
    Inscrit en
    Juillet 2006
    Messages
    883
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur web/mobile

    Informations forums :
    Inscription : Juillet 2006
    Messages : 883
    Points : 1 066
    Points
    1 066
    Par défaut
    Ce reuse address a quand même un comportement bizarre...
    Mettons ce scénario:
    Je lance le serveur (avec l'option reuse)
    Un client se connecte
    Je coupe le serveur
    Je veux le relancer, impossible
    Le client fait un send, qui a l'air de fonctionner
    Je relance le serveur, nickel
    Un nouveau send du client est un échec

    Où est passé le premier send de mon client ?

    Citation Envoyé par iReNu Voir le message
    Oui si j'ai bien compris il aurait fallu fermer le socket client et ensuite le serveur pour que ce soit quelque chose de plus correcte.
    J'ai bien essayer de fermer, côté serveur, les sockets clients avant le serveur lui-même; mais rien n'y fait.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 0
    Dernier message: 16/03/2015, 14h03
  2. socket.error: [Errno 98] Address already in use
    Par Jackbalek dans le forum Réseau/Web
    Réponses: 0
    Dernier message: 09/07/2014, 10h13
  3. Erreur "java.net.BindException: Address already in use: JVM_Bind"
    Par baaab dans le forum Développement Web en Java
    Réponses: 1
    Dernier message: 15/06/2013, 17h35
  4. could not bind socket !address already in use
    Par slimix00 dans le forum Linux
    Réponses: 2
    Dernier message: 23/08/2012, 09h55
  5. Address already in use
    Par horkets dans le forum Réseau
    Réponses: 4
    Dernier message: 29/10/2006, 21h08

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo