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] Pb send() et recv()


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] Pb send() et recv()
    Salut,

    J'implemente une classe pour l'utilisation des sockets et mes premiers tests ne sont pas concluants. Le message que le serveur affiche est depourvu d'espaces et suivi de caracteres parasites plus ou moins bien reconnus par l'encodage. Voici le code pour l'envoi du message (c'est une classe dont le serveur et le client derive) :
    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::envoi(std::string msg)
    {
    	const char *buf = msg.c_str();
    	int len = strlen(buf);
    	int err = send(desc_sock, buf, len, 0);
    	if(err == -1){
    		print_error("échec de l'envoi");
    		return false;
    	}else if(err != len){
    		print_error("message partiellement envoyé");
    		return false;
    	}
    	return true;
    }
     
    void SOCKET_INIT::recep(string msg, string addr)
    {
    	//à implémenter suivant les besoins
    	cout << addr << " > " << msg << endl;
    }
     
    void SOCKET_INIT::close()
    {
    	if(desc_sock != INVALID_SOCKET){
    		shutdown(desc_sock, 2); //ferme l'envoi et la reception
    	}
    }
     
    void SOCKET_INIT::print_error(string error)
    {
    	//à implementer suivant les besoins
    	cout << "ERREUR: " << error << endl;
    }
    Et voici le traitement du 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
    29
    30
    31
    32
    33
    34
    35
    void SOCKET_SERVER::ecoute()
    {
    	int error = listen(desc_sock, max_connexion);
     
    	if(error == -1){
    		print_error("impossible d'écouter sur le port");
    		return;
    	}
     
    	/**** acceptation d'un client ****/
    	int desc_new; //descripteur de la nouvelle connexion
    	socklen_t sin_size = sizeof(struct sockaddr_in);
    	desc_new = accept(desc_sock, (struct sockaddr *) &their_addr, &sin_size);
     
    	if(desc_new == -1){
    		print_error("connexion entrante refusée");
    		return;
    	}
     
    	while(true){
     
    		/**** réception du message ****/
    		char buffer[MAXDATASIZE];
    		int num_byte = recv(desc_new, buffer, MAXDATASIZE, 0);
     
    		if(num_byte == -1){
    			print_error("impossible de lire le message entrant");
    			return;
    		}
     
    		/**** traitement du message ****/
    		string addr = inet_ntoa(their_addr.sin_addr);
    		recep(buffer, addr);
    	}
    }
    Je pense que l'erreur provient de l'envoi. Je sais qu'en C on fait en general quelque chose comme ca :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    // créer le buffer pour copier la chaîne
    size_t size = message.size() + 1;
    char * buffer = new char[ size ];
    // copier la chaîne dans le buffer
    strncpy( buffer, message.c_str(), size );
    Mais je voudrais quelque chose qui soit du C++.

    Merci de me faire de vos remarques/conseils (ou autres).

  2. #2
    Expert �minent
    Avatar de M�dinoc
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 41
    Localisation : France

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par d�faut
    Tu ne transmets pas le z�ro terminal (et d'apr�s Emmanuel Delahaye, il ne faut pas le transmettre). Tu dois donc le rajouter c�t� serveur ou construire une string � partir de ton buffer et de la longueur recue.
    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.

  3. #3
    Expert confirm�

    Homme Profil pro
    Ing�nieur syst�mes et r�seaux
    Inscrit en
    F�vrier 2007
    Messages
    4 253
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rh�ne (Rh�ne Alpes)

    Informations professionnelles :
    Activit� : Ing�nieur syst�mes et r�seaux
    Secteur : High Tech - Multim�dia et Internet

    Informations forums :
    Inscription : F�vrier 2007
    Messages : 4 253
    Billets dans le blog
    3
    Par d�faut
    Je ne vois ce qui emp�cherai le transfert d'un 0 � la fin de la chaine...
    Mais bon... quand on parle de strings il y a plusieurs choses:
    - Un 0 n'est pas *forc�ment* la fin d'une chaine (essayes en Shift-JIS par exemple). Il faut donc, comme dit Medinoc, ou bien sp�cifier la longueur de la ch�ine *avant* l'envoi, ou bien sp�cifier le code-page, ou bien convenir d'un code-page pr�d�fini entre le client et le serveur (sachant que celui par d�faut dans C++ n'est peut �tre pas le m�me).
    - D'autre part, rien ne force send() (on est en TCP l�) � tout envoyer d'un coup... c'est une �criture bufferis�e. Du coup si le client fait un send(aaa,1000) puis send(bbb,500).... et le serveur int len = recv(buffer,buffersize);, la seule restriction sur len est que: 0 < len <= buffersize
    ... len peut tr�s bien valoir 1500 (les deux sends regroup�s) ou 128 (le premier send coup�), etc....

    Il semble que tu ne prennes pas compte cette longueur re�ue... (tu l'utilises juste pour tester une valeur d'erreur)

  4. #4
    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
    Je vois pas pourquoi j'ajouterais la fin de chaine au buffer de reception. Lorsque je declare
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    char buffer[MAXDATASIZE];
    il a deja un caractere de fin chaine a la position MAXDATASIZE, non ? Pour moi, la fonction recv() ne fait que remplir avec des donnees l'espace memoire alloue a buffer. (Ce qui pourrait effectivement etre critique si recv() recevait MAXDATASIZE+1 caracteres ...)

    Admettons que send() envoie successivement 1000 puis 500 caracteres. recv() n'a aucun moyen de savoir que le message de 1500 caracteres qu'elle recoit est en fait un message de 1000 et un message de 500. A part envoyer la fin de chaine, je vois pas trop ce que je peux faire.

  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
    J'ai ajoute le zero au buffer et le code fonctionne... Donc apparemment ce n'est pas a la declaration du char que le zero est ajoute.

    Par contre, j'ai un autre probleme. Les espaces que contiennent les textes envoyes sont systematiquement supprimes alors que tous les caracteres (meme ceux ne faisant pas partie de la norme ASCII) fonctionnent.

  6. #6
    Expert confirm�

    Homme Profil pro
    Ing�nieur syst�mes et r�seaux
    Inscrit en
    F�vrier 2007
    Messages
    4 253
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rh�ne (Rh�ne Alpes)

    Informations professionnelles :
    Activit� : Ing�nieur syst�mes et r�seaux
    Secteur : High Tech - Multim�dia et Internet

    Informations forums :
    Inscription : F�vrier 2007
    Messages : 4 253
    Billets dans le blog
    3
    Par d�faut
    Oublie l'ASCII.... send et recv envoient du BINAIRE et rien d'autre... donc des octets, sans se pr�occuper de ce qu'il y a dedans...

    Tu envoies des octets avec 0x20 ? Ca doit les recevoir de l'autre cot�...
    Donc il doit y avoir un probl�me � la reception (voir � l'affichage... ca serait pas la premi�re fois que c'est juste l'output de v�rification qui merdoie ! ).

    Sinon char tableau[1000] d�clare un tableau de 1000 chars sur la pile ... rien de plus...
    En gros, le processeur va juste modifier le pointeur de pile de 1000 octets... Si il y avait des 0 avant, tant mieux... si il y avait que des 0xCD... ben tu auras que du 0xCD !
    A toi de mettre le 0 sur le dernier octet: tableau[999] !

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. Sur un socket : send et recv ou read et write ?
    Par M�dinoc dans le forum R�seau
    R�ponses: 35
    Dernier message: 05/11/2009, 15h51
  2. socket send et recv
    Par sebatlante dans le forum R�seau
    R�ponses: 24
    Dernier message: 29/08/2007, 01h34
  3. Question sur les fonctions "send()" et "recv(
    Par damien99 dans le forum MFC
    R�ponses: 6
    Dernier message: 10/02/2006, 20h47
  4. Socket et send();
    Par deviante dans le forum C++
    R�ponses: 2
    Dernier message: 13/01/2006, 20h32

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