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 - recv() ne fonctionne pas


Sujet :

C++

  1. #1
    Membre averti
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2012
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Services à domicile

    Informations forums :
    Inscription : Juin 2012
    Messages : 41
    Par défaut Socket - recv() ne fonctionne pas
    Bonjour,

    J'ai décidé il y a peu de créer deux classe pour faciliter l'utilisation des sockets.

    L'une des classe permet de démarrer un socket en mode serveur, l'autre en mode client. Mais il semblerais que quand j'essaie de transmettre une donnée, le recv() ne fonctionne pas. J'ai essayé de trouver l'erreur par moi même, mais rien a faire, les données ne passent pas.

    Voici les headers des classes :

    Le client
    --------

    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
     
    class client
    {
    private :
    	bool starter_check;
    	string buffer;
    	int erreur;
    	SOCKET sock;
    	SOCKADDR_IN sin;
     
    	#if defined (WIN32)
    		WSADATA WSAData;
    	#endif
    public :
            // Creation de la socket
    	client(int port, string ip_g);
    	//destruction de la socket
    	~client();
    	// Envoie/reception des données
    	bool getData();
    	bool sendData();
    	// getters/setters
            char *getBuffer();
            bool setBuffer(char *newbuffer);
    };
    le serveur
    ---------

    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
     
    class server
    {
    private :
            bool starter_check;
            string buffer;
            int erreur;
            SOCKET sock;
            SOCKADDR_IN sin;
            SOCKET csock;
            SOCKADDR_IN csin;
     
            #if defined (WIN32)
                    WSADATA WSAData;
            #endif
     
    public :
            // Creation de la socket
    	server(int port);
            //destruction de la socket
    	~server();
            // Envoie/reception des données
    	bool getData();
    	bool sendData();
            // getters/setters
            char* getBuffer();
            bool setBuffer(char *newbuffer);
    };
    et voici les 2 main.cpp (les données sont envoyées entre deux programmes)

    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
     
        // LE PREMIER MAIN
        char *buffer = "un test";
        bool check;
        server *s = new server(23);
     
        check = s->setBuffer(buffer);
        check = s->sendData();
     
        delete s;
     
        return 0;
     
     
     
     
        // LE DEUXIEME MAIN
     
        bool check;
        server *c = new client(23, "127.0.0.1");
     
        check = c->getData();
        char *buffer = c->gerBuffer();
     
        cout << buffer << endl;
     
        delete c;
     
        return 0;

    Je pense que l'erreur est peut-être due a la structure de mon code, mais il se peux que j'ai fais une faute lors de la création des sockets. C'est pour cela que je vais aussi mettre le cpp des classes :

    server.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
    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
    109
    110
    111
    112
    113
    114
    115
    116
    117
     
    #include "server.h"
    server::server(int port)
    {
    	#if defined (WIN32)
    		erreur = WSAStartup(MAKEWORD(2,2), &WSAData);
    	#else
    		erreur = 0;
    	#endif
     
    	if(!erreur)
    	{
    		sock = socket(AF_INET, SOCK_STREAM, 0);
            if(sock != INVALID_SOCKET)
    		{
    			// Ouverture de la socket = ok 
     
    			//configuration
    			sin.sin_addr.s_addr = htonl(INADDR_ANY);
    			sin.sin_family = AF_INET;
    			sin.sin_port = htons(port);
     
                int ok = bind(sock, (SOCKADDR*)&sin, sizeof(sin));
     
    			if(ok != SOCKET_ERROR)
    			{
    				ok = listen(sock, 5);
     
    				if(ok != SOCKET_ERROR)
    				{
                        int size = sizeof(csin);
                        csock = accept(sock, (SOCKADDR*)&csin, &size);
                        starter_check = true;
    				}
    				else
                        starter_check = false;
    			}
    			else
                    starter_check = false;
    		}
    		else
                starter_check = false;
    	}
    	else
            starter_check = false;
     
    }
    server::~server()
    {
                   closesocket(csock);
                   closesocket(sock);
                   #if defined (WIN32)
                        WSACleanup();
                   #endif
    }
     
    // -----------------------------------
    // -----------------------------------
     
    bool server::getData()
    {
        // Verifie si le constructeur n'a pas planté
        vector<char> buffer_p(5000);
        if(starter_check == false)
        {
            return false;
        }
     
        int ok = recv(sock, buffer_p.data(), sizeof(buffer_p), 0);
     
        if(ok != SOCKET_ERROR)
        {
            buffer_p.resize(ok);
            buffer = buffer_p.data();
            return true;
        }
        else
            return false;
    }
    bool server::sendData()
    {
            //Veriefie si le constructeur n'a pas planté
            if(starter_check == false)
            {
                    return false;
            }
            // Ceci est une fonction qui converti les string en char*
            char *buffer_p = stringToChar(buffer);
     
            int ok = send(sock, buffer.c_str(), sizeof(buffer), 0);
     
            if(ok != SOCKET_ERROR)
            {
                    return true;
            }
            else
                return false;
    }
     
     
    // ------------------------------
    // ------------------------------
     
     
    char* server::getBuffer()
    {
        return stringToChar(buffer);
    }
    bool server::setBuffer(char *newbuffer)
    {
        if(starter_check == false)
        {
                return false;
        }
        buffer = newbuffer;
        return true;
    }
    Client.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
    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
     
    #include "client.h"
     
    client::client(int port, string ip_g)
    {
            #if defined (WIN32)
                    erreur = WSAStartup(MAKEWORD(2,2), &WSAData);
            #else
                    erreur = 0;
            #endif
     
    	if(!erreur)
    	{
    		// Creation de la socket
    		sock = socket(AF_INET, SOCK_STREAM, 0);
     
    		// Connection configuration
    		sin.sin_addr.s_addr = inet_addr(ip_g.c_str());
    		sin.sin_family = AF_INET;
    		sin.sin_port = htons(port);
     
            // If connection
            if(connect(sock, (SOCKADDR*)&sin, sizeof(sin)) != SOCKET_ERROR)
    		{
    			starter_check = true;
    		}
    		else
                starter_check = false;
     
    	}
    	else
            starter_check = false;
    }
     
     
    client::~client()
    {
                closesocket(sock);
     
                #if defined (WIN32)
                        WSACleanup();
                #endif
     
    }
     
    //  ********************
    //  ********************
     
     
    bool client::getData()
    {
        // Verifie si le constructeur n'a pas planté
        vector<char> buffer_p(5000);
    	if(starter_check == false)
    	{
    		return false;
    	}
     
        int ok = recv(sock, buffer_p.data(), sizeof(buffer_p), 0);
     
    	if(ok != SOCKET_ERROR)
    	{
    		buffer_p.resize(ok);
    		buffer = buffer_p.data();
    		return true;
    	}
    	else
    		return false;
     
    }
    bool client::sendData()
    {
            //Verifie si le client n'a pas planté
            if(starter_check == false)
            {
                    return false;
            }
            char *buffer_p = stringToChar(buffer);
     
            int ok = send(sock, buffer.c_str(), sizeof(buffer), 0);
     
            if(ok != SOCKET_ERROR)
            {
                    return true;
            }
            else
                    return false;
    }
     
     
    // ------------------------------
    // ------------------------------
     
     
    char* client::getBuffer()
    {
        return stringToChar(buffer);
    }
    bool client::setBuffer(char *newbuffer)
    {
        if(starter_check == false)
        {
                return false;
        }
    	buffer = newbuffer;
    	return true;
    }
    Je sais que les deux dernier "codes" sont assez grands, mais je ne les ai que mis au cas ou.

    Merci de votre aide .

  2. #2
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    je ne vois nulle part de boucle d'écoute et lecture.
    La seule façon que ton client se connecte à ton serveur c'est qu'il émette la connexion exactement entre les lignes 27 et 32 de ton fichier serveur.cpp. Et encore, il pourra n'être que seul.

    Je serai surpris que tous les flags d'erreur que tu check et lèves passent.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Membre averti
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2012
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Services à domicile

    Informations forums :
    Inscription : Juin 2012
    Messages : 41
    Par défaut
    Merci de ta réponse rapide,

    Si je comprends bien, je devrais déplacer le code entre les ligne de 27 à 32 dans la fonction senData() et en faire un boucle ?

  4. #4
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Je ne comprends pas comment tu arrives à cette conclusion avec mon post.

    Le fonctionnement du client c'est de se connecter à un serveur, et d'y envoyer des données. Mais aussi d'en recevoir le plus souvent.
    Si tu regardes la doc, recv est bloquant. Partant de là, recv devrait être threadé.
    Typiquement, ça ressemble à ça chez moi, dans un vieux 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
    void CChatClient::Listening()
    {
    	while (m_bConnected)
    	{
    		std::string datas = Recieve();
    		if (datas.length())
    		{
    			std::cout<<datas<<std::endl;
    		}
    	}
    }
    std::string CChatClient::Recieve()
    {
    	char buffer[BUFFER_MAX+1] = {0};
    	std::string datas;
    	int iLastRecievedBufferLen = 0;
    	do {
    		iLastRecievedBufferLen = recv(m_pSocket, buffer, BUFFER_MAX, 0);
    		datas += buffer;
    	} while (iLastRecievedBufferLen == BUFFER_MAX);
    	m_bConnected = (iLastRecievedBufferLen > 0);
    	return datas;
    }
    Listening étant bien entendu dans son propre thread.

    Le principe d'un serveur c'est qu'il écoute en continu sur le port pour accepter les connexions entrantes. Sinon il aura bien du mal à ce qu'un quelconque client s'y connecte..
    Donc de la même manière, tu dois avoir un thread qui fait plus ou moins ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    while ((SOCKET pSock = accept()) != INVALID_SOCKET)
    {
        // en général on maintient une liste des clients, ou on crée un thread, ou ....
    }
    Ca peut être le main thread, mais lis la doc, accept est bloquante.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  5. #5
    Membre averti
    Homme Profil pro
    Développeur Web
    Inscrit en
    Juin 2012
    Messages
    41
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Services à domicile

    Informations forums :
    Inscription : Juin 2012
    Messages : 41
    Par défaut
    Merci beaucoup pour cette réponse.

    Je vois que j'ai encore beaucoup a apprendre concernant les socket !
    Mais tu as rendu tout ça plus clair !

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

Discussions similaires

  1. Shell a travers socket ne fonctionne pas
    Par Voleurdepoules dans le forum Réseau
    Réponses: 5
    Dernier message: 19/05/2015, 13h23
  2. Socket, recv et select qui ne marche pas
    Par Zapan dans le forum Réseau
    Réponses: 18
    Dernier message: 30/06/2006, 20h19
  3. UNION qui ne fonctionne pas
    Par r-zo dans le forum Langage SQL
    Réponses: 7
    Dernier message: 21/07/2003, 10h04
  4. Un Hint sur un PopupMenu ne fonctionne pas !!??
    Par momox dans le forum C++Builder
    Réponses: 6
    Dernier message: 26/05/2003, 16h48
  5. ca ne fonctionne pas (generateur auto-incrémentant)
    Par tripper.dim dans le forum SQL
    Réponses: 7
    Dernier message: 26/11/2002, 00h10

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