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] - Buffer & Read() ou Recv()


Sujet :

C++

  1. #1
    Membre éclairé Avatar de jacquesh
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    269
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2005
    Messages : 269
    Par défaut [SOCKET] - Buffer & Read() ou Recv()
    Bonjour à tous.

    je débute avec les socket en C++ et j'ai un problème dans la reception quand il y a beaucoup de données (en tous cas bcp plus que le buffer peut absorbé)

    voila des extraits du 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
    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
     
    ...
        char buf[PACKET_SIZE];
     
        string message[] = {
            "authinfo user XXXX@free.fr\n",
            "authinfo pass YYYY\n"
        } ;
     
        for (int i=0;i<sizeof(message)/sizeof *message;++i){
     
        buf[0] = 0x00 ;
        ReadBuff(GetSocketId(),buf,(PACKET_SIZE)) ;
     
            // WRITE SOCKET
            if (int j = (write(GetSocketId(),message[i].c_str(),message[i].length()))<0){        
                cerr << "Impossible d'ecrire dans le socket !" << endl;
            } else {            
                if (DEBUG)
                    cout << "Envoi de la commande : code("<< j << ")  " << message[i] << endl;
            }
     
        }
     
    int Nntp::ReadBuff(int socket_id,char *buffer, unsigned int length) {
     
    	int nl, nr ;
    	nl = length ;
     
    	while (nl > 0){
    		memset(buffer, 0x0, PACKET_SIZE) ;
    		nr = read(socket_id,buffer,nl) ;
    		if (nr < 0) return nr ;
    		else if (nr == 0) {
    			cout << buffer ;
    			break ;
    		} else {
    			cout << buffer ;
    		}
    		nl -= nr ;
    		buffer += nr ;
    		if ( *(buffer-1)=='\n' && *(buffer-2) == '\r'){
    			break ;
    		}
    		break ;
    	}
    	*buffer = 0x00; 
    	return (0); 
     
    }
    quelqu'un connait il un moyen de pouvoir gerer les buffers des sockets quelque soit la taille des données à obtenir et le type (Binaire ou Texte).

    j'ai trouvé beaucoup de tuto mais a chaque fois c'est juste pour envoyer 'Hello World' mais pas une grande masse de données.

    si quelqu'un peut m'expliquer l'algorithme a utilisé pour pouvoir tout récupérer..

    merci d'avance.

  2. #2
    Membre éprouvé Avatar de hansaplast
    Homme Profil pro
    Artisant logiciel
    Inscrit en
    Septembre 2005
    Messages
    951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Artisant logiciel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 951
    Par défaut
    perso, j'ai fait comme ca :

    paquet 1 => envoie la taille du buffer

    paquet 2 a n => envoi le buffer...

    et ainsi de suite.

  3. #3
    Membre éclairé Avatar de jacquesh
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    269
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2005
    Messages : 269
    Par défaut
    bijour,

    ok mais si les données retourné dépasse le PACKET_SIZE défini au début du code ?

    dans mon exemple quand je faut l'authentification au près du serveur pas de problème ; les données sont petites ; par contre quand je demande un grand nombre de données mon packet s'arrete à 1090 bytes et stop il s'arrete là (données vérifié avec Ethereal)

    pourquoi ??

  4. #4
    Membre chevronné Avatar de niglo
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    379
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Bas Rhin (Alsace)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 379
    Par défaut
    Citation Envoyé par jacquesh
    pourquoi ??
    C'est normal, il atteint la limite maximale d'un paquet ! Ton message va être transféré en plusieurs paquets IP. Pour toi, ca va être transparent : l'émetteur fait un "write" sur un socket et de l'autre côté, tu fais un read pour attendre les données ! C'est write qui va se charger d'envoyer plusieurs paquets et read va les capter et les assembler !

  5. #5
    Membre éprouvé Avatar de hansaplast
    Homme Profil pro
    Artisant logiciel
    Inscrit en
    Septembre 2005
    Messages
    951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Artisant logiciel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 951
    Par défaut
    et donc, il faut boucler, opour recomposer ta donnée initiale.

    d'où ma proposition d'envoyer en premier la taille de la donnée, ainsi, tu sait quand sortir de ta boucle,e t tout recomposer

  6. #6
    Membre éclairé Avatar de jacquesh
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    269
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2005
    Messages : 269
    Par défaut
    ca c'est ce que dit le protocole TCP/IP je suis d'accord ; mon problème doit être la facon de l'implementé en C++ la bufferisation je pense...

    quand je fait strace ./monprog voila ce que j'obtiens :

    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
     
    ...
    socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 4
    connect(4, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("164.1.152.1")}, 28) = 0
    writev(4, [{"\0\36", 2}, {"\240\243\1\0\0\1\0\0\0\0\0\0\4news\4free\2fr\0\0\1\0\1"..., 30}], 2) = 32
    read(4, "\0022", 2)                     = 2
    read(4, "\240\243\201\200\0\1\0\34\0\2\0\2\4news\4free\2fr\0\0\1"..., 562) = 562
    close(4)                                = 0
    read(3, 0xbfd2ad20, 1024)               = -1 ENOTCONN (Transport endpoint is not connected)
    connect(3, {sa_family=AF_INET, sin_port=htons(119), sin_addr=inet_addr("212.27.42.138")}, 16) = 0
    read(3, "200 nnrp10-1.free.fr NNRP Servic"..., 1024) = 79
    write(1, "200 nnrp10-1.free.fr NNRP Servic"..., 79200 nnrp10-1.free.fr NNRP Service Ready - newsmaster@proxad.net (posting ok).
    ) = 79
    write(3, "authinfo user XXXXXXXXX@free"..., 37) = 37
    write(1, "Envoi de la commande : code(0)  "..., 69Envoi de la commande : code(0)  authinfo user XXXXXXXXXX@free.fr
    ) = 69
    write(1, "\n", 1
    )                       = 1
    read(3, "381 PASS required\r\n", 1024)  = 19
    write(1, "381 PASS required\r\n", 19381 PASS required
    )   = 19
    write(3, "authinfo pass YYYYYYYYY\r\n", 24) = 24
    write(1, "Envoi de la commande : code(0)  "..., 56Envoi de la commande : code(0)  authinfo pass YYYYYYYYY
    ) = 56
    write(1, "\n", 1
    )                       = 1
    read(3, "281 Ok\r\n", 1024)             = 8
    write(1, "281 Ok\r\n", 8281 Ok
    )               = 8
    write(3, "list\r\n", 6)                 = 6
    write(1, "Envoi de la commande : code(0)  "..., 38Envoi de la commande : code(0)  list
    ) = 38
    write(1, "\n", 1
    )                       = 1
    shutdown(3, 2 /* send and receive */)   = 0
    close(3)                                = 0
    write(1, "Fermeture du socket :: id=3\n", 28Fermeture du socket :: id=3
    ) = 28
    munmap(0xb7f19000, 4096)                = 0
    exit_group(0)                           = ?
    et quand j'envoi la commande 'list', je regarde dans ethereal et je n'est que les 1090 premier bytes pas la suite ???

  7. #7
    Membre éclairé Avatar de jacquesh
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    269
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2005
    Messages : 269
    Par défaut
    Citation Envoyé par hansaplast
    et donc, il faut boucler, opour recomposer ta donnée initiale.

    d'où ma proposition d'envoyer en premier la taille de la donnée, ainsi, tu sait quand sortir de ta boucle,e t tout recomposer
    c'est pas ce que je fait dans l'exemple fourni dans mon post ? le while dans la methode
    Nntp::ReadBuff

  8. #8
    Membre éprouvé Avatar de hansaplast
    Homme Profil pro
    Artisant logiciel
    Inscrit en
    Septembre 2005
    Messages
    951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Artisant logiciel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 951
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int Nntp::ReadBuff(int socket_id,char *buffer, unsigned int length)
    commetn connait tu la valeur de ta var "length"?

  9. #9
    Membre éclairé Avatar de jacquesh
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    269
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2005
    Messages : 269
    Par défaut
    ca correspond à un un

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    #define PACKET_SIZE    1024

  10. #10
    Membre éprouvé Avatar de hansaplast
    Homme Profil pro
    Artisant logiciel
    Inscrit en
    Septembre 2005
    Messages
    951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Artisant logiciel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 951
    Par défaut
    Citation Envoyé par jacquesh
    ca correspond à un un

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    #define PACKET_SIZE    1024
    ok.

    maintenant, imagine, tu envoie un buffer de 4000 octets, comment sait tu que tu doit recuperer pile poile cette quantitée?

  11. #11
    Membre éclairé Avatar de jacquesh
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    269
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2005
    Messages : 269
    Par défaut
    ben c bien ca le problème.. je ne sait pas a l'avance la taille que je vais recevoir....

  12. #12
    Membre éprouvé Avatar de hansaplast
    Homme Profil pro
    Artisant logiciel
    Inscrit en
    Septembre 2005
    Messages
    951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Artisant logiciel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 951
    Par défaut
    Citation Envoyé par jacquesh
    ben c bien ca le problème.. je ne sait pas a l'avance la taille que je vais recevoir....
    bein, c'est a toi de l'envoyer, bon un code sera peut etre plus parlant :
    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
    bool mySocketClient::litMSG()
    {
      if ( !DataIncomming ) {
      litTailleMSG();
     } else {
      litCorpsMSG(); //les données entrent
      if ( tailleDataRestante <= 0) 
      {   
       finaliseDATA(); 
       return true;
      }
     }
     return false;
     //a implementer dans les classe qui heritent de cet objet : le traitement a faire sur les données recues
    }
    dans ce code quii receptionne les données, tu lit d'abord al taille du message, puis el message.

    comment implementer ca?

    coté envoie de données, tu fait un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    socket->ecrit(tailleMsessage)
    socket->ecrit(message)
    et coté client :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    socket->lit(tailleMessage)
    tant que tailleMessage > 0
      socket->lit(message, NBOctetsLuts)
      tailleMessage -= NBOctetsLuts
    finTQ
    un truc du genre, ca te convient?

  13. #13
    Membre éclairé Avatar de jacquesh
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    269
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2005
    Messages : 269
    Par défaut
    sur l'idée j'ai compris

    mais une chose demeur flou

    socket->lit(tailleMessage)
    comment puis-je lire la taille du message sachant que ce n'est pas moi qui envoi la donnée (serveur NNTP de free dans mon exemple)

  14. #14
    Membre éprouvé Avatar de hansaplast
    Homme Profil pro
    Artisant logiciel
    Inscrit en
    Septembre 2005
    Messages
    951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Artisant logiciel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 951
    Par défaut
    Citation Envoyé par jacquesh
    sur l'idée j'ai compris

    mais une chose demeur flou

    socket->lit(tailleMessage)
    comment puis-je lire la taille du message sachant que ce n'est pas moi qui envoi la donnée (serveur NNTP de free dans mon exemple)
    ok!
    bein, dans tous les cas, je pense que la taille doit etre declarée, je en sait aps a quoi corespond un serveur NNTP.

    mais renseigne toi sur le protocole correpsondant

  15. #15
    Membre éclairé Avatar de jacquesh
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    269
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2005
    Messages : 269
    Par défaut
    bon j'vé fouillé dans la RFC ...

    Merci pour toutes tes explications... je te tiens au courant..

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 : buffer envoyé != buffer reçu
    Par apesle dans le forum Réseau
    Réponses: 4
    Dernier message: 03/03/2009, 11h54
  3. [socket] résultat de la fonction recv
    Par alana dans le forum Débuter
    Réponses: 4
    Dernier message: 22/07/2008, 13h14
  4. [Socket] Buffer et TCP
    Par rgz dans le forum Web & réseau
    Réponses: 7
    Dernier message: 14/10/2003, 13h59

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