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] appel de recv() depuis le client


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    309
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 309
    Par défaut [socket][UDP][TCP] notions client-serveur
    Salut,

    J'ai creer des classes C++ pour me simplifier l'utilisation des sockets : SOCKET_CLIENT et SOCKET_SERVER derivent de SOCKET_INIT. SOCKET_INIT contient notamment les fonctions d'envoi et de reception. Le code est prevu pour fonctionner en TCP et en UDP selon ce que l'utilisateur declare au constructeur.

    Voici le code qui pose probleme :
    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
    bool SOCKET_INIT::recep()
    {
    	int num_byte;
    	char buffer[MAXDATASIZE+1];
     
    	/**** réception du message ****/
    	if(get_type() == TCP){
    		//reception TCP
    		num_byte = recv(desc_new, buffer, sizeof(buffer)-1, 0);
    	}else{
    		//reception UDP
    		socklen_t sin_size = sizeof(struct sockaddr_in);
    		num_byte = recvfrom(desc_sock, buffer, sizeof(buffer)-1, 0, (struct sockaddr *) &dest_addr, &sin_size);
    	}
     
    	if(num_byte != 0){
    		if(num_byte != SOCKET_ERROR){
     
    			/**** traitement du message ****/
    			buffer[num_byte] = 0; //ajout du caractère de fin de chaîne
    			string addr = inet_ntoa(dest_addr.sin_addr);
    			print_recep(addr, buffer);
    			return true;
     
    		}else{
    			print_error("impossible de lire le message entrant");
    			return false;
    		}
    	}else{
    		print_info("client " + tostr(desc_new) + " déconnecté");
    		return false;
    	}
    }
    Cette fonction est commune au client et au serveur. Elle fonctionne parfaitement lors de son appel depuis le client(UDP), le serveur(UDP) et le serveur(TCP). Mais lors de l'appel depuis le client(TCP), elle n'attend pas l'arrivee du message et renvoie directement l'erreur "impossible de lire le message entrant" (bref, elle renvoie -1).

    Y-a-il une precaution particuliere a prendre lors qu'on veut recevoir des donnees avec le client en mode connecte ?

    Merci

  2. #2
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Ton code semble correct.

    Une question maintenant, le descripteur de ton socket est il membre de la classe SOCKET_INIT ?

    J'ai l'impression qu'en TCP, il lit le socket "desc_new" qui je devine a un sens sur le serveur mais qui n'est pas initialisé sur le client (puisque c'est un client)

    En UDP, il lit dans "desc_sock"

    donc soit ta classe n'a pas de membre "socket" soit le membre n'est pas initialisé et dans tous les cas, tu semble lire dans le mauvais socket.
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    309
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 309
    Par défaut
    Bien vu. "desc_new" n'a pas de sens sur le client et n'est donc pas initialise.

    Mais ca m'ennuie de remplacer ma fonction SOCKET_INIT::recep() par SOCKET_CLIENT::recep() et SOCKET::recep() juste a cause d'une variable. D'un autre cote, je ne vois pas comment detecter si le socket est serveur ou client. A part en declarant un booleen au constructeur SOCKET_INIT(). Ce qui ne serais pas forcement plus elegant.

    Un conseil ?

  4. #4
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Je pense que tu as un petit problème de conception/architecture de tes classes.

    Tu as un socket serveur SOCKET_SERVER qui dérive de SOCKET_INIT si tu veux pour lequel tu fais un bind(), listen() et accept(). Le send() et le recv() sur cette classe n'ont pas de sens

    Tu as un socket client SOCKET_CLIENT qui dérive de SOCKET_INIT si tu veux pour lequel le send() et le recv() ont un sens. bind(), listen() et accept() n'ont pas de sens pour cette classe.

    Ce socket client SOCKET_CLIENT peut être issu/créé par un connect() ou bien issu/créé du resultat du accept() mais dans les 2 cas, c'est un socket client. Maintenant, dans cette classe SOCKET_CLIENT tu peux créer/avoir besoin d'un flag qui indique si le socket est créé par connect() et donc explicitement par le programme ou bien si le socket est créé par un serveur et donc la conséquence du accept().
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    309
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 309
    Par défaut
    Voici la "structure" de mes classes :

    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
    SOCKET_INIT{
         create_socket();
         adressage() = 0; //virtuelle pure
         send();
         recv();
    };
     
    SOCKET_SERVER : SOCKET_INIT{
         adressage(); //appel de bind()
         listen();
         accept();
    };
     
    SOCKET_CLIENT : SOCKET_INIT{
         adressage(); //appel de bind()
         connect();
    };
    SOCKET_INIT est sensee contenir tout ce qui est commun au client et au serveur. De cette maniere, j'obtiens un code "factorise".
    C'est pour cette raison que send() et recv() sont dans SOCKET_INIT.

    Mais, comme tu l'as mis en evidence, il semblerait que, en mode TCP, le recv()-serveur ne soit pas identique au recv()-client.

    Je devrais donc declarer recv() virtuelle pure dans SOCKET_INIT et surcharger une version dans SOCKET_CLIENT et une autre dans SOCKET_SERVER.

    Mais, comme je te disais, les 2 versions seront tres similaires et ca m'embette de dupliquer du code pour si peu.

    Je doute qu'il y ait une meilleure solution mais si quelqu'un en a une, qu'il m'en fasse part.

    PS: Je ne comprends pas pourquoi tu dis que send() et recv() n'ont pas de sens dans SOCKET_SERVER.

  6. #6
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Citation Envoyé par Tymk Voir le message
    SOCKET_INIT est sensee contenir tout ce qui est commun au client et au serveur. De cette maniere, j'obtiens un code "factorise".
    OK, c'est la base même

    Citation Envoyé par Tymk Voir le message
    Mais, comme tu l'as mis en evidence, il semblerait que, en mode TCP, le recv()-serveur ne soit pas identique au recv()-client.
    En mode TCP, le recv() et le send() sur un socket serveur (socket qui a fait bind(), listen() et accept()) n'ont pas de sens.
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

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

Discussions similaires

  1. [EJB3.1] Comment appeler des EJB depuis un client Swing
    Par levolutionniste dans le forum Java EE
    Réponses: 2
    Dernier message: 25/03/2012, 20h49
  2. Connexion depuis un client en socket
    Par Achille39 dans le forum Administration
    Réponses: 0
    Dernier message: 27/09/2010, 19h40
  3. appel de webservice depuis le client GWT
    Par dolfendo dans le forum GWT et Vaadin
    Réponses: 8
    Dernier message: 05/11/2009, 18h59
  4. [SOAP][PHP]Appel d'une fonction depuis un client
    Par sergeh dans le forum XML/XSL et SOAP
    Réponses: 1
    Dernier message: 01/11/2009, 16h43
  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