Bonjour,
comment tester avant de faire un send() que la socket est valide ?
si j'utilise la fonction select(), elle me renvoie toujours que la socket placée dans le FD_SET est valide, puisqu'elle me renvoie toujours 1.
Une idée ?
@+
Bonjour,
comment tester avant de faire un send() que la socket est valide ?
si j'utilise la fonction select(), elle me renvoie toujours que la socket placée dans le FD_SET est valide, puisqu'elle me renvoie toujours 1.
Une idée ?
@+
On peut faire des tests a chaque etape de la creation du socket.
Sinon un test au niveau de "connect" pour un socket "client"
ou au niveau de "bind" pour un socket "serveur".
Ces étapes précédants logiquement l'envoi de données.
non, pas si tu fais une connexion permanente.
Dans une connexion permanente, tu te connectes avec la fonction connect(), qui te renvoie ton descripteur (ta socket).
Puis tu peux faire des send() ou des recv() sur cette socket.
Or avant de faire un send(), j'aimerais savoir si mon serveur n'est pas tombé.
Donc je teste avec select(), mais ça ne marche pas !!
@+
Tu peux essayer de faire un send de "test" avant ton vrai send pour savoir si la connesxion est toujours OK ! Sinon, tu peux essayer de pinger le serveur mais si il répond ca voudra pas dire que ta socket est toujours OK. Je pense qu'un send "test" est une bonne solution en testant sa valeur de retour !
non, car un send() marche toujours même sur une socket() "bidon"
tu es sur de ca ??Envoyé par olive_le_malin
D'apres le man de send (http://linux.com.hk/penguin/man/2/se...an2/send.2.inc)
-->Error :
ENOTCONN
The socket is not connected, and no target has been given.
pour l'avoir souvent fait, je confirme send() ne fonctionne pas si ta socket ou ton descripteur sont non valide.
Et généralement tu ne test pas d'envoyé, tu gardes plutot ton message dans un coin après tu essayes d'envoyer, si ce la foire comme tu as gardé ton message tu peux toujours ré-essayer plus tard.
heu, oui ... exact !
Ben alors là, je me retrouve tout bête !
Bon mais alors comment faire pour la tester cette socket() ?
Parce que j'ai un thread qui tourne pour affecter le descripteur si et eulement si il estcessaire de le réaffecter.
Le descripteur est donc global, et dans d'autres threads, on peut faire des send() dessus.
L'idée c'est que les send() marchent toujours, car le thread de surveillance a détecté que la socket est tombée.
@+
Bon le seul truc que j'ai trouvé pour avoir une détection de socket perdue, c'est de faire :
En effet tant que la socket est vivante le ret = 0, et dés qu'elle est morte il vaut 1
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 FD_SET readfds; TIMEVAL t; memset(&t, 0, sizeof(t)); FD_ZERO(&readfds); FD_SET(*s, &readfds); ret = select(0, &readfds, NULL, NULL, &t); if(ret == 1) { TraceError("select() failed with error %d.", WSAGetLastError()); closesocket(*s); *s = 0; }
@+
Pourrait tu preciser un peu plus le contexte. Este ce que la partie qui reçoit est implementé par toi. Dans ce cas, tu peux prevoir à intervalle reguliere de lancer des echo. Si tu reçoit pas de reponses, dans ce cas, tu peux considerer que la connection est out...
Bonjour,
je veux que mon thread de surveillance vérifie toutes les secondes que ma socket est bien active, sinon il se charge de re-créer la connexion vers le serveur, et donc de ré-affecter un descripteur valide à ma socket.
Je ne veux pas créer un pooling interne (echo dont tu parles) car à mon sens ce n'est pas nécessaire.
Par exemple un recv(socket, .... ) détecte immédiatement la perte de la socket. Alors comment ça se fait qu'avec un select() je n'arrive pas à le faire avec la manière ... car je considère que ce que j'ai fait est vraiment tout pourri, mais pour le moment ça marche ...
@+
FD_SET readfds;
TIMEVAL t;
memset(&t, 0, sizeof(t));
FD_ZERO(&readfds);
FD_SET(*s, &readfds);
ret = select(0, &readfds, NULL, NULL, &t);
if(ret == 1 && readfds.fd_count == 1)
{
//--> un évènement sur le read a eu lieu :
// - soit il y a des données sur la socket
// - soit la remote socket est morte
}
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 voilà, y a 2 choix possibles ... c'est ça le problème !! Je vais voir ce que donne le exceptfds, et s'il est mis à 1 lorsque la socket est déconnecté, mais je pense pas
Mais d'apres le man de socket, et vu que tu es en mode connecté, normalement, si ton socket n'est plus connecté, les primitive send, recv et autre doivent renvoyer -1... Tu n'as pas essayé ça?
Pour savoir si ta socket est mort ou s'il y a des donnes a lire, essai de faire un recv, si en retour tu as 0 ou que le buffer passse a recv une taille de 0, cela veux dire que ta socket est morte.
C'est peut-etre pas tres propree comme methode mais ca marche.
Je suis étonné que ça marche. Tu as testé? Car recv est bloquant, enfin à moins de creer une socket non bloquante, auquel cas, il me semble qu'on peut juste savoir qu'aucunes données ne sont disponnible en lecture... Mais cela ne veut pas dire que la connection est out. Ca peu aussi vouloir dire qu'aucune donnée n'a été envoyée.Envoyé par caesarvanou
En revanche je me suis rappelé qu'un de mes programme s'interompait si je tentait d'utiliser un socket connecté apres rupture de la connection. Et dans man socket(2), j'ai trouvé ça :
Il y a peut etre une piste à suivre dans l'interception de ce signale....Un signal SIGPIPE est envoyé au processus tentant d'écrire sur une socket inutilisable, forçant les programmes ne gérant pas ce signal à se terminer.
Bonne continuation...
Pour une socket bloquante, recv() retourne zéro si la connexion a été "gentiment" fermée de l'autre coté.
Si la connexion est "tombée" de l'autre coté, recv() retournera -1 avec une erreur ECONNRESET/WSAECONNRESET (10054)
Par contre, le coup du zéro ne doit plus marcher quand la socket est non-bloquante (signification ambigüe).
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
Partager