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

C++ Discussion :

Socket, errno 24 sur accept()


Sujet :

C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2013
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2013
    Messages : 27
    Points : 15
    Points
    15
    Par défaut Socket, errno 24 sur accept()
    Hello

    Je travail actuellement sur un programme client/serveur et je fait des tests de reconnection. Pour ne pas trop rentrer dans les détails, je lance mon programme client, je lance le serveur, et je les interromps l'un et l'autre en les relançants pour vérifier que le client se reconnecte bien au serveur après une déconnections et inversement.

    Lorsque j'interromps le client et que je le relance, aucun soucis, le serveur le reprend sans problème, mais lorsque j'interromps le serveur et que je le relance j'ai un errno 24 sur la fonction accept() (côté serveur). Je n'ai cette erreur seulement lorsque j'interromps, puis, relance le serveur tout en laissant le client ouvert. Là où je suis un peu étonné c'est que dans un cas "normal" où je lance le serveur et le client pour la première fois je n'ai pas cette erreur.

    J'ai fait quelques recherches mais je n'ai malheuresement rien trouvé qui ne fonctionne .

    Avez-vous déjà rencontré cette erreur? :o

    Merci d'avance

  2. #2
    Membre expérimenté Avatar de SkyZoThreaD
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Juillet 2013
    Messages
    584
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Juillet 2013
    Messages : 584
    Points : 1 615
    Points
    1 615
    Par défaut
    L'erreur 24 sur accept signifie "too many open files". Essaye de vérifier que le socket est bien fermé quand tu interrompt le serveur. Si oui, donnes-nous le code qui est sensé faire ce taf

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 182
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 182
    Points : 12 316
    Points
    12 316
    Par défaut
    24 ou 0x24 ?

    ERROR_BAD_LENGTH
    24 (0x18)
    The program issued a command but the command length is incorrect.
    ERROR_SHARING_BUFFER_EXCEEDED
    36 (0x24)
    Too many files opened for sharing.

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2013
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2013
    Messages : 27
    Points : 15
    Points
    15
    Par défaut
    @SkyZoThreaD: J'ai bien vérifié, la socket est fermé avant de relancer le serveur mais j'ai toujours la même erreur.

    @bacelar Effectivement tu as bien fait de demander, c'est un errno 0x18 (j'avais pas tilté que c'était en hexadécimal ^^').


    Du coup, voici une partie de mon code source:

    main.cpp
    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
    #include <iostream>			
    #include <thread>			
     
    #include "socket.h"
     
    using namespace std;
     
    int main()
    {
        while (sock_s.sock_listen == -1)
        {
        	sock_s.sock_listen = socket_creation();     //crée la socket
        } 
     
        thread T1_accept(socket_chain_accept, sock_s.sock_listen);    //thread acceptant les connexions
        thread T2_check(socket_check);      //thread vérifiant la connexion client en envoyant un message (send())
     
        string data;
        while (1)
        {
        	sleep(1);
        	cout << "Wait client..." << endl;
        	while (sock_s.csock.size() != 0)     //Si il y a un client de connecté...
        	{
        		cout << "Message : ";
        		cin >> data;
        		if(data == "exit")
        		{
        			shutdown(sock_s.sock_listen, 2);
        			close(sock_s.sock_listen);
        			T1_accept.detach();
    			T2_check.detach();
     
    			cout << "FINISH" << endl;
        			return 0;
        		}
       		socket_send((char*)data.c_str(), sock_s.csock[0]);
        	}
        }
     
        return 0;
    }
    socket.h
    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
    typedef int SOCKET;
     
    struct sock_s
    {
    	SOCKET sock_listen = -1;
    	vector<SOCKET> csock;
    }sock_s;
     
    int socket_listen(SOCKET sock = sock_s.sock_listen, int max_connection = 5)
    {
        if(listen(sock, max_connection) == -1)
        {
            cout << "ERROR : Socket listen failed!" << endl << "      : errno = " << errno << endl;
            return -1;
        }
     
        sockaddr_in target;
     
        socklen_t _size = sizeof(sock);
        SOCKET csock = accept(sock, (sockaddr*)&target, &_size);
     
        if(csock == -1)
        {
            cout << "ERROR : Socket accept connection failed!" << endl << "      : errno = " << hex << errno << endl;
            return -1;
        }
     
        return csock;
    }
     
    void socket_chain_accept(SOCKET sock = sock_s.sock_listen)
    {
    	SOCKET csock;
    	while(1)
    	{
    		csock = socket_listen(sock_s.sock_listen, 999);
    		if(csock != -1)
    		{
    			sock_s.csock.push_back(csock);
    		}
    	}
    }
    Je n'ai mis ici que les partis me parraissant interessantes pour facilité la lisibilité mais si vous voulez voir l'intégralité il n'y a pas de soucis

  5. #5
    Membre expérimenté Avatar de SkyZoThreaD
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Juillet 2013
    Messages
    584
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Juillet 2013
    Messages : 584
    Points : 1 615
    Points
    1 615
    Par défaut
    Dans socket_listen tu as:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    socklen_t _size = sizeof(sock);
    la taille d'un int ?!?!
    Je mettrai plus:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    socklen_t _size = sizeof(target);
    Un sockaddr aurait du mal a tenir dans un int à mon avis...
    mais bon je ne suis pas un expert...

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 182
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 182
    Points : 12 316
    Points
    12 316
    Par défaut
    Houlà, ça manque de rigueur.
    Si ça marche, c'est que c'est tombé en marche.

    Il ya tellement de truc étrange que je pense qu'il faudra commencer par remettre tout un peu plus d'équerre.

    1- C'est quoi ce .h avec des définitions ?
    Dans les .h, c'est les déclarations.

    2- C'est quoi ces "while tant qu'erreur" et autre while(1) ???

    3- dégagez moi ces Sleep !

    4- C'est quoi cette valeur par défaut de paramètre correspondant à un champ du variable globale ? Je savais même pas que ça pouvais compiler tellement c'est illogique.

    ...

    Il faut être rigoureux quand on programme mais encore plus quand on fait du multi-threading.
    C'est tellement fouillis qu'on ne peut pas raisonnablement appréhender les mécanismes de synchronisation des threads.

    P.S.: SkyZoThreaD a tout à fait raison, je l'avais vu, mais il y a tellement de chose d'autres qui ne vont pas pour comprendre comment, par miracle, ça ne plante pas, que j'ai oublié de le rajouter.

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2013
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2013
    Messages : 27
    Points : 15
    Points
    15
    Par défaut
    Effectivement c'est plus logique comme ça ^^' Je suis en train d'apprendre à manier les sockets et ça ne m'avait pas marqué mais maintenant que tu le dit ça parrait évident. Merci pour la correction

    J'ai donc changé ça mais j'ai toujours le même problème :/
    Je continu à faire des recherches sur l'erreur errno.

    EDIT: Désolé bacelar je n'avais pas vu ton message. Je vais faire du ménage et je vous redonne tout ça. Et à propos des sleep ils me permettent de prendre le temps de voir les messages d'erreurs sans que ça ne défile à une vitesse folle. Bon si je n'avais pas mis des while(1) je n'aurais peut être pas ce problème... Certe ^^' Bon je vais faire du ménage et je reviens

  8. #8
    Membre expérimenté Avatar de SkyZoThreaD
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Juillet 2013
    Messages
    584
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Juillet 2013
    Messages : 584
    Points : 1 615
    Points
    1 615
    Par défaut
    Si l'erreur est bien:
    ERROR_BAD_LENGTH
    24 (0x18)
    The program issued a command but the command length is incorrect.
    Alors la correction que je t'ai donné était peut-être la cause de l'erreur 0x18
    Mais tu as peut-être un(ou des) autre souci ailleurs.
    Evite l'utilisation de threads si tu n'es pas famillier avec eux. Mon pseudo veut tout dire (même s'il ne veux aussi rien dire).
    Il y a les problèmes de sychro, de partage de ressources... c'est vraiment pas simple. Tu n'as pas moyen de faire sans?
    Bon courage en tout cas on attend ton code retravaillé

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2013
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2013
    Messages : 27
    Points : 15
    Points
    15
    Par défaut
    Hum... Enfaite j'ai besoin de thread infini, pour pouvoir vérifier en permanence la liste des clients et je n'ai pas trouvé le moyen de relancer le thread une fois terminé sans boucle infini :/ Bref, je vais revoir ça

    Après pour l'erreur j'ai toujours la même avec ou sans ta correction mais quoi qu'il en soit j'avais bel et bien une erreur à ce niveau là (et pas que )

  10. #10
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Citation Envoyé par moi4567 Voir le message
    Hum... Enfaite j'ai besoin de thread infini
    En dehors du contexte, ça fait peur ce genre de remarque !
    Mais bon, on comprend quand même !

  11. #11
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 129
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 129
    Points : 33 061
    Points
    33 061
    Billets dans le blog
    4
    Par défaut
    Salut,

    tu as cette erreur sur le serveur, mais est-ce que le client réagit bien au reboot serveur ?
    Est-ce qu'il ferme correctement sa socket avant d'en réouvrir une vers le serveur ?

    Sinon, je vois pas ce qu'il y a de choquant à voir des boucles infinies dans du code réseau... c'est même assez habituel et normal.

    Je n'ai malheureusement plus de code serveur en C++ à te montrer.
    Mais en gros, tu devrais avoir un thread qui écoute les connections, et un autre qui gère les clients.
    Le main thread peut s'occuper des connections.
    Après, vu ton faible nombre de clients, tu peux threader chacun d'eux sur le serveur.

    Par contre, quitte à vouloir faire du C++, fais vraiment du C++..
    Une classe serveur, c'est un bon début.

    En plus, il manque la moitié du code.
    socket_creation par exemple, on le devine comment ?

  12. #12
    Membre expérimenté Avatar de SkyZoThreaD
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Juillet 2013
    Messages
    584
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Juillet 2013
    Messages : 584
    Points : 1 615
    Points
    1 615
    Par défaut
    Sinon, je vois pas ce qu'il y a de choquant à voir des boucles infinies dans du code réseau... c'est même assez habituel et normal.
    Des boucles infinies ok (sans while(1) quand même). Mais la boucle principale dans un thread c'est moyen. Le concept veut plus qu'elle soit dans le main thread et chaque client lance un thread à la connexion. non?

    edit: oops parlé trop vite. C'est bien ce que tu as dit

Discussions similaires

  1. socket avec timeout sur accept
    Par Trunks dans le forum Windows
    Réponses: 8
    Dernier message: 29/01/2010, 16h21
  2. Socket et SSL sur mon poste de travail windows
    Par bigsister dans le forum Langage
    Réponses: 5
    Dernier message: 25/02/2007, 00h25
  3. [SOCKET] Client UDP sur système Unix
    Par be_tnt dans le forum Développement
    Réponses: 1
    Dernier message: 14/04/2006, 21h31
  4. Socket Delphi 7 sur Delphi 2005 ???
    Par rpoulin dans le forum Web & réseau
    Réponses: 2
    Dernier message: 24/12/2005, 09h33
  5. [Sockets] Timeout sur accept() ?
    Par MikB dans le forum Développement
    Réponses: 2
    Dernier message: 30/12/2003, 17h22

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