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

Entrée/Sortie Java Discussion :

[Socket] Comment casser un read bloquant ?


Sujet :

Entrée/Sortie Java

  1. #1
    Membre habitué

    Inscrit en
    Janvier 2006
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 188
    Points : 142
    Points
    142
    Par défaut [Socket] Comment casser un read bloquant ?
    voici le problème et ma modélisation:
    le programme est un proxy mais juste le coté serveur suffit pour illustrer le probleme.
    En fait au lieu de simplement lancer un Thread pour chaque nouvelle connexion entrante, je passe par un InputConnectionManager qui contient un Vector avec tous les Threads (InputConnection).
    j'utilise donc dans le serveur une methode de se Manager qui me retourne le Thread que je lance donc ensuite.
    Lors de la fermeture du server (Ctrl-C), je veux fermer proprement toutes les connexions. j'ai donc mis un ShutdownHook dans le serveur.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
            Runtime.getRuntime().addShutdownHook(new Thread() {
                public void run() {
                    close();
                }
            });
    Dans ce close, je force la fin de tout mes Threads (input connexion) un par un et j'attends leur fin (join).
    Tout ça marche très bien à un détail près: mes Threads restent bloqués sur des read (socket). C'est le fonctionnement normal: le client est censé m'envoyer une commande ou bien fermer la socket mais je fais mes tests en telnet et cela est un peu soppo. De plus tant qu'un seul des clients ne m'a pas envoyé quelque chose, le serveur n'est pas fermé puisqu'il reste sur le join. Il n'y a pas un moyen de break les read bloquant afin de forcer la fermeture ?

    (les threads sont une boucle infinie: réception commande/ envoi réponse qui ne se break que lorsque la cmd est QUIT, c'est pour ça que je me retrouve avec un read bloquant)

    Merci d'avance pour l'aide

    PS: je viens de penser à un truc: est ce possible d'utiliser des signaux en java ? le serveur pourrait propager le Ctrl-C à tous les Threads. ça devrait killer les reads et avec un ShutdownHook je pourrai être propre. je verrai ça se soir, là je dois bouger.

  2. #2
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 084
    Points
    16 084
    Par défaut
    Killer les threads (Thread.stop) , c'est possible, mais:
    1. c'est mal
    2. ca ne marchera pas dans ton cas (socket read)

    Seule solution, fermer le socket (Socket.close)

  3. #3
    Membre habitué

    Inscrit en
    Janvier 2006
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 188
    Points : 142
    Points
    142
    Par défaut
    je sais que killer un thread c'est mal mais je ne sais pas comment faire...
    je tente de fermer la socket, mais ça ne marche pas :s
    le Thread reste bloqué sur le read de la socket alors que via une autre classe (mon manager) j'appelle sa methode stopThread dans laquelle je ferme les buffer reader/writter et la socket.
    j'ai mis des traces, et quoi qu'il arrive, la methode stopThread n'est exécutée qu'après le read débloqué :'(
    une solution ?

  4. #4
    Expert éminent sénior
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    En plaçant un timeout sur la socket çà ne pourrait pas faire l'affaire?


    void connect(SocketAddress endpoint, int timeout)
    Connects this socket to the server with a specified timeout value.

  5. #5
    Membre habitué

    Inscrit en
    Janvier 2006
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 188
    Points : 142
    Points
    142
    Par défaut
    merci pour l'idée, mais cela ne règle pas mon problème.
    En effet, j'utilise un BufferedReader,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    in=new BufferedReader(new InputStreamReader(sock.getInputStream()));
    et la Socket sock provient d'un accept d'une ServerSocket. Il ne me semble pas y avoir de timer configurable dessus :s

    Je pense qu'il faudrait directement agir sur le Reader, mais je n'ai rien trouvé ni dans java.io.Reader ni dans java.io.BufferedReader.
    Je ne pense pas que les signaux existent en Java mais il doit bien y avoir un moyen de communiquer avec un Thread !
    Que pensez vous des exceptions ? le problème c'est que je ne pense pas que l'on puisse la dirigé vers un id spécifique si ?


    Rq d'après la javadoc, le TimeOut ne semble de plus concerner que l'établissement de la connexion.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SocketTimeoutException - if timeout expires before connecting

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    361
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 361
    Points : 429
    Points
    429
    Par défaut
    Salut,

    Je ne vois pas où est le problème.

    Tu fais une méthode close() dans ton serveur qui ferme ainsi toutes les connexions + son socket d'écoute, et tu l'appel depuis le Thread principal (ici ton serveur doit être dans un Thread à part, ainsi que chaque connexion cliente).

    P.S: java.nio c'est mieux.

    P.S2: si tu utilises l'invite de commandes, tu dois faire SHIFT + ENTRER pour envoyer le message, et pas ENTRER uniquement sinon le readLine du BufferedReader ne se déclenche car il attend un \r\n (c'est ce qui délimite les lignes).

  7. #7
    Membre habitué

    Inscrit en
    Janvier 2006
    Messages
    188
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 188
    Points : 142
    Points
    142
    Par défaut
    oki, c'est de ma faute
    en vous faisant un code exemple illustrant mon pb, j'ai trouvé par hasard...
    je faisais ça dans la methode pour fermer mes Threads handler de connection:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
                try{;
                    in.close();
                    out.close();
                    sock.close()
                }
                catch(IOException e){
                    System.out.println("Error Closing socket...");
                    return;
                }
    le in.close() attend la fin du read qui se trouve dans la boucle du run.
    en mettant le sock.close en premier ça marche :p
    sorry et merci encore
    ++

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

Discussions similaires

  1. Probleme de read() bloquant sur un socket.
    Par gregb34 dans le forum C++
    Réponses: 26
    Dernier message: 16/04/2008, 15h11
  2. [SOCKET] comment rendre send() bloquant
    Par damien99 dans le forum Visual C++
    Réponses: 4
    Dernier message: 23/02/2007, 16h15
  3. [sockets]Comment intéragir avec une socket php ?
    Par le Daoud dans le forum Entrée/Sortie
    Réponses: 3
    Dernier message: 31/10/2005, 10h50
  4. [Socket] Comment faire du multi-client ?
    Par eric30eric dans le forum Web & réseau
    Réponses: 5
    Dernier message: 05/01/2005, 21h39
  5. [linux] socket comment savoir si est un client est d
    Par Mascos dans le forum Réseau
    Réponses: 14
    Dernier message: 04/08/2004, 12h05

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