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 :

Problème sockets perte de connexion


Sujet :

Entrée/Sortie Java

  1. #1
    Membre à l'essai
    Inscrit en
    Mars 2007
    Messages
    8
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 8
    Points : 10
    Points
    10
    Par défaut Problème sockets perte de connexion
    2 composants A et B dialoguent par sockets. Les 2 sont à la fois serveurs et clients entre eux.
    Lorsque le composant B est arrêté brutalement, j'ai une SocketException "Connection reset by peer : write error" en essayant d'écrire du client A vers le serveur B (ce qui est logique).
    Ce qui est moins logique c'est que lorsque j'essaie de détecter la perte de connexion entre A et B, on me répond toujours que la socket cliente côté A est encore active.
    J'ai essayé les méthodes clientSocket.isClosed(), clientSocket.isConnected(), mais elles me répondent toujours la même chose avant et après la perte de connexion.

    Comment faire, lorsque mon composant B tombe, pour détecter la perte de connexion du côté de A ?

    Merci pour vos réponses.

  2. #2
    Rédacteur

    Avatar de millie
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    7 015
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 7 015
    Points : 9 818
    Points
    9 818
    Par défaut
    En fait, la manière dont est implementée read (et write) fait que l'on ne modifie pas la socket (le fait que ce soit fermé ou connecté) lorsqu'il y a un problème de connexion mais envoie directement l'exception.

    Normalement, lors d'une exception "ConnectionResetByPeer", on suppose que la transmission a échouée et on arrête. Il est nécessaire de bien fermer (du côté client) le socket avec close() pour voir que read retourne une valeur < 0 pour voir que la transmission est finie

    Donc pour vérifier la perte de connexion, il est nécessaire de tenter d'écrire ou de lire pour voir si on recoit un SocketException


    Pour information, voici le code natif (sous windows) de read :
    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
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    JNIEXPORT jint JNICALL
    Java_java_net_SocketInputStream_socketRead0(JNIEnv *env, jobject this, 
    					    jobject fdObj, jbyteArray data, 
    					    jint off, jint len, jint timeout) 
    {
        char *bufP;
        char BUF[MAX_BUFFER_LEN];
        jint fd, newfd;
        jint nread;
     
        if (IS_NULL(fdObj)) {
            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed");
    	return -1;
        } 
        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID); 
        if (fd == -1) {
    	NET_ThrowSocketException(env, "Socket closed");
    	return -1;
        }
     
        /*
         * If the caller buffer is large than our stack buffer then we allocate
         * from the heap (up to a limit). If memory is exhausted we always use
         * the stack buffer.
         */
        if (len <= MAX_BUFFER_LEN) {
    	bufP = BUF;
        } else {
    	if (len > MAX_HEAP_BUFFER_LEN) {
    	    len = MAX_HEAP_BUFFER_LEN;
    	}
    	bufP = (char *)malloc((size_t)len);
    	if (bufP == NULL) {
    	    /* allocation failed so use stack buffer */
    	    bufP = BUF;
    	    len = MAX_BUFFER_LEN;
    	}
        }
     
     
        if (timeout) {
    	if (timeout <= 5000 || !isRcvTimeoutSupported) {
    	    int ret = NET_Timeout (fd, timeout);
     
    	    if (ret <= 0) {
    		if (ret == 0) {
     		    JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
    				    "Read timed out");
    		} else if (ret == JVM_IO_ERR) {
    		    JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "socket closed");
    		} else if (ret == JVM_IO_INTR) {
    		    JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
    				    "Operation interrupted");
    		}
    		if (bufP != BUF) {
    		    free(bufP);
    		}
    		return -1;
    	    }
     
    	    /*check if the socket has been closed while we were in timeout*/ 
    	    newfd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
    	    if (newfd == -1) {
    		NET_ThrowSocketException(env, "Socket Closed");
    		return -1;
    	    }  
    	}
        }
     
        nread = recv(fd, bufP, len, 0);
        if (nread > 0) {
    	(*env)->SetByteArrayRegion(env, data, off, nread, (jbyte *)bufP);
        } else {
    	if (nread < 0) {
    	    /*
    	     * Recv failed.
    	     */
    	    switch (WSAGetLastError()) {
    	        case WSAEINTR:
    		    JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", 
    			"socket closed");
    		    break;
     
    		case WSAECONNRESET:
    		case WSAESHUTDOWN:
    		    /*
    		     * Connection has been reset - Windows sometimes reports
    		     * the reset as a shutdown error.
    		     */
    		    JNU_ThrowByName(env, "sun/net/ConnectionResetException",
    			"");
    		    break;
     
    	        case WSAETIMEDOUT :
                        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
                                       "Read timed out");
    		    break;
     
    		default:
    		    NET_ThrowCurrent(env, "recv failed");
    	    }
    	}
        }
        if (bufP != BUF) {
    	free(bufP);
        }
        return nread;
    }
    On voit que si l'appel système recv échoue, il y a envoie direct d'une exception sans modifier l'état du socket.

Discussions similaires

  1. PQsocket() can't get socket descriptor - Perte de connexion
    Par rivsc dans le forum Administration
    Réponses: 0
    Dernier message: 17/07/2014, 10h41
  2. Socket et détection d'une perte de connexion
    Par Tigrounette dans le forum Entrée/Sortie
    Réponses: 6
    Dernier message: 27/09/2007, 20h36
  3. [Forum] Problème de pertes de connexions
    Par Invité dans le forum Mode d'emploi & aide aux nouveaux
    Réponses: 8
    Dernier message: 19/03/2007, 18h35
  4. [MFC] Problème Socket + Connexion SQL
    Par BananaUltra3C dans le forum MFC
    Réponses: 6
    Dernier message: 20/05/2005, 17h41
  5. [JNDI] Problème en cas de perte de connexion
    Par Marc_P dans le forum API standards et tierces
    Réponses: 3
    Dernier message: 19/10/2004, 15h45

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