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

Réseau C Discussion :

Ajuster la taille du buffer pour recv


Sujet :

Réseau C

  1. #1
    Membre régulier Avatar de figarojuju
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    133
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Avril 2006
    Messages : 133
    Points : 73
    Points
    73
    Par défaut Ajuster la taille du buffer pour recv
    Bonjour,
    j'ai fait un petit programme qui envoie une requête HTML via la méthode GET et qui affiche le résultat récupéré (méthode recv) dans un buffer.
    Ça marche, c'est déjà pas mal pour moi !!!
    Mais, l'affectation au pif de la taille du buffer pour stocker la réponse du serveur ne me plait pas :

    • y a-t-il moyen de connaitre la taille du fichier index.html avant de le charger dans mon buffer et ainsi écrire la bonne taille de buffer ?
    • est-ce que c'est mieux de choisir une petite taille de buffer et de créer une boucle sur la fonction recv pour récurer au fur et à mesure la réponse du serveur ?


    Qu'en pensez-vous ?

    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
     
     
    #include <errno.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <sys/types.h>
    #include <arpa/inet.h>
    #include <unistd.h>
     
    #define PORT 80
    #define ip "xxxxxxxxxxxx"
     
    int main(int argc,char * argv[]){
     
    //structure du socket :
        struct sockaddr_in adresse;
        adresse.sin_family=AF_INET;
        adresse.sin_port = htons(PORT);
        adresse.sin_addr.s_addr=inet_addr(ip);
        int longueur=sizeof(adresse);
     
    //creation du socket :
        int socketSiteHtml;
        if((socketSiteHtml=socket(AF_INET,SOCK_STREAM,0))<0){
        fprintf(stderr,"la socket a echouee\n");
        perror("ouverture socket");
        }
     
    //connexion au site distant :
        if(connect(socketSiteHtml,(struct sockaddr *) &adresse,longueur)==0)
            {
            printf("connexion réusie\n");
            }
        else
            {
            perror("Connexion");
            exit(EXIT_FAILURE);
            }
    //le message
    int n;
    char * message;
    char * buffer[1000];
    message="GET /index.php HTTP/1.1\r\nHost:www.truc.fr\n\r\n";
        if(send(socketSiteHtml,message,strlen(message)+1,0)==-1){
            perror("send");
            return EXIT_FAILURE;
            }
        if((n=recv(socketSiteHtml,buffer,sizeof(buffer),0))<0){
            perror("recv()");
            return EXIT_FAILURE;
            }    
        else printf("%s \n",buffer);
        close(socketSiteHtml);
    return 0;
    }

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 368
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 368
    Points : 23 622
    Points
    23 622
    Par défaut
    Bonjour,

    Citation Envoyé par figarojuju Voir le message
    y a-t-il moyen de connaitre la taille du fichier index.html avant de le charger dans mon buffer et ainsi écrire la bonne taille de buffer ?
    Non. Ce fichier peut d'ailleurs être très long, c'est pourquoi prévoir un buffer de la bonne taille n'est pas une bonne idée de toutes façons. Cette taille t'est indiquée en principe par le serveur dans un des champs de l'entête, ce qui permet à ton navigateur (quand tu en utilises un en temps normal) de t'afficher une barre de progression. Si cette info n'est pas disponible, on ne peut pas savoir à l'avance quand le fichier va être fini. La barre de progression fait en général une sorte de ping-pong, à ce moment-là.

    Tant que c'est un fichier ordinaire, le serveur peut le savoir. Si c'est une page auto-générée par un script CGI ou PHP, c'est au dit script de préciser cette info, s'il en est capable.

    Est-ce que c'est mieux de choisir une petite taille de buffer et de créer une boucle sur la fonction recv pour récurer au fur et à mesure la réponse du serveur ?
    Oui.

    L'optimal, dans l'absolu, est de créer un buffer adapté aux capacités de ta machine et à la taille de ta RAM, sinon tu fais beaucoup d'accès disques et d'appels système (un buffer de 16 octets, par exemple, c'est trop petit :-) ). Par contre, il faut se souvenir que tu ne sais pas dans quel environnement ton programme va tourner et que, dans tous les cas, il ne sera pas tout seul. Ça veut dire que, par exemple, le plus efficace est d'utiliser toute la mémoire disponible (c'est ce que fait l'O.S. avec le cache disque) mais que tu ne peux pas te permettre de le faire car si un autre programme a décidé de faire pareil, ou que l'utilisateur compte le faire pour faire des calculs, par exemple, tu vas plomber leurs performances pour rien.

    Je pense que le mieux est d'allouer un buffer correspondant à une page de swap, mais je dis cela de manière complètement empirique.

  3. #3
    Membre régulier Avatar de figarojuju
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    133
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Avril 2006
    Messages : 133
    Points : 73
    Points
    73
    Par défaut
    Merci pour la réponse, je vais chercher à écrire la boucle !!

    Néanmoins, la question que je me posais est par rapport à la définition de recv :
    Si un message est trop long pour tenir dans le buffer, les octets supplémentaires peuvent être abandonnés suivant le type de socket utilisé
    .

    J'imagine que ce n'est pas le cas en mode connecté (sock_stream), et que le protocole garantit qu'aucun octet n'est perdu. Est-ce correct ?

    Donc, si j'ai un message du serveur qui dépasse en taille celui de mon buffer, je reçois une première partie (de taille buffer), et le protocole TCP fait en sorte qu'il m'est renvoyé par le suite le complément à transmettre sans que je n'ai rien à gérer ? (hormis un nouvel appel à recv).

    Merci encore pour votre aide et bonne soirée

  4. #4
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Déjà, l'idée de vouloir stocker tout le document dans un buffer n'est vraiment pas très bonne. Pense plutôt à le stocker dans un fichier. C'est-à-dire faire quelque chose du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    fopen();
    while (recv())
        fwrite();
    Autres choses ?
    fclose();
    A moins que ton but soit justement d'étudier le protocole HTTP, tu devrais peut-être aussi te tourner vers des APIs ou bibliothèques spécialisées (comme l'API WinInet sous Windows par exemple) plutôt que de travailler directement avec. Sinon il y a aussi la commande HTTP HEAD qui permet de récupérer juste l'en-tête d'un document, qui fournit sa taille entre autres.

  5. #5
    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 : 61
    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
    Points : 50 367
    Points
    50 367
    Par défaut
    Citation Envoyé par Melem Voir le message
    comme l'API WinInet sous Windows par exemple
    API WinInet : http://msdn.microsoft.com/en-us/libr...(v=VS.85).aspx

    API WinHTTP : http://msdn.microsoft.com/en-us/libr...(v=VS.85).aspx

    Quelques différences dans ces API :
    WinInet utilise le cache local, WinHTTP non
    WinInet utilise des clés dans le registre HKEY_LOCAL_USER, winHTTP non. Pour cette raison, WinInet ne doit pas être utilisés par un service windows.
    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
    .

  6. #6
    Membre régulier Avatar de figarojuju
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    133
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Avril 2006
    Messages : 133
    Points : 73
    Points
    73
    Par défaut Merci de vos réponses
    Bonjour,
    mon but est de découvrir les sockets et leur programmation, par curiosité...
    Je vais suivre vos conseils :

    • stocker dans un fichier
    • ensuite, c'est vrai qu'il existe des libraries spécialisées. Je suis sous Ubuntu, je vais essayer libcurl (c'est celle que j'ai directement trouvée en cherchant sur google)


    Merci encore et bonne journée

    PS : une liste de librairies http://curl.haxx.se/libcurl/competitors.html

  7. #7
    Expert éminent sénior
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 360
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 360
    Points : 20 378
    Points
    20 378
    Par défaut
    Citation Envoyé par figarojuju Voir le message
    Bonjour,
    mon but est de découvrir les sockets et leur programmation, par curiosité...
    alors tu pourras me donner un coup de main alors
    je suis en train de programmer mon jeu en mode LAN et je souhaite créer des jeux en réseau..

  8. #8
    Membre régulier Avatar de figarojuju
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    133
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Avril 2006
    Messages : 133
    Points : 73
    Points
    73
    Par défaut Avec ouverture de fichier
    Bonsoir,
    j'ai donc suivi vos conseils et j'ai modifié mon programme de la manière suivante :
    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
     
    #include <errno.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <sys/types.h>
    #include <arpa/inet.h>
    #include <unistd.h>
     
    #define PORT 80
    #define ip "xx.xx.xx.xx"
     
    int main(int argc,char * argv[]){
     
    //structure du socket :
        struct sockaddr_in adresse;
        adresse.sin_family=AF_INET;
        adresse.sin_port = htons(PORT);
        adresse.sin_addr.s_addr=inet_addr(ip);
        int longueur=sizeof(adresse);
     
    //creation du socket :
        int socketSiteHtml;
        if((socketSiteHtml=socket(AF_INET,SOCK_STREAM,0))<0){
        fprintf(stderr,"la socket a echouee\n");
        perror("ouverture socket");
        }
     
    //connexion au site distant :
        if(connect(socketSiteHtml,(struct sockaddr *) &adresse,longueur)==0)
            {
            printf("connexion réusie\n");
            }
        else
            {
            perror("Connexion");
            exit(EXIT_FAILURE);
            }
     
    //le message
        int n;
        int taille_buffer=2000;
        char * message;
        char * buffer[taille_buffer];
        message="GET /index.php HTTP/1.1\r\nHost:www.xxx.fr\r\n\r\n";
     
    //envoi de la requete
        if(send(socketSiteHtml,message,strlen(message)+1,0)==-1){
            perror("send");
            return EXIT_FAILURE;
            }
     
    //reception du message
        FILE * fi=NULL;
        char nomFichierHtml[10]="html.txt";
        int fin=0;
        int octets_recus=0;
     
        if((fi=fopen(nomFichierHtml,"w+"))==NULL){
            perror("fopen");
            exit(EXIT_FAILURE);
        }
        while(fin==0){
            memset(buffer,0,taille_buffer);
            octets_recus=recv(socketSiteHtml,buffer,taille_buffer,0);
            if(octets_recus<0){
                perror("recv");
                exit(EXIT_FAILURE);
            }
            if(octets_recus>0){
                printf("octets recus : %i\n",octets_recus);
                fputs(buffer,fi);
            }
            if(octets_recus==0){
                fin=1;        
                }
            }
     
    //lecture du fichier
        rewind(fi);
        int curseur=0;
        curseur=fgetc(fi);
        while(curseur!=EOF){
            printf("%c",curseur);
            curseur=fgetc(fi);
        }
     
        fclose(fi);
        close(socketSiteHtml);
    return 0;
    }
    Qu'en pensez-vous ?

    Merci encore de vos conseils et bonne soirée

    PS : je regarderai ensuite pour la libcurl...

  9. #9
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Impec .

  10. #10
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Melem Voir le message
    Impec .
    Non, pas tout à fait !!!

    Citation Envoyé par figarojuju Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    //le message
        int n;
        int taille_buffer=2000;
        char * message;
        char * buffer[taille_buffer];
        message="GET /index.php HTTP/1.1\r\nHost:www.xxx.fr\r\n\r\n";
    Qu'en pensez-vous ?
    Ben j'en pense que ce qu'il y a en rouge c'est pas tiptop...

    Ensuite, puisqu'il s'agit juste pour toi d'un exercice, tu pourrais essayer de découper les actions de ton main en modules élémentaires ce qui rendrait ton code plus facilement évolutif...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  11. #11
    Membre régulier Avatar de figarojuju
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    133
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Avril 2006
    Messages : 133
    Points : 73
    Points
    73
    Par défaut
    Bonjour,
    j'ai créé des fonctions simples pour un peu de modularité...ça commence à ressembler à du code un peu construit quand même !
    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
     
    #include <errno.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <sys/types.h>
    #include <arpa/inet.h>
    #include <unistd.h>
     
    #define PORT 80
    #define ip "xxx.70"
     
    int main(int argc,char * argv[]){
     
    //declaration des fonctions
        void ecrire(int *,FILE *,int);
        void lecture(FILE *);
     
    //structure du socket :
        struct sockaddr_in adresse;
        adresse.sin_family=AF_INET;
        adresse.sin_port = htons(PORT);
        adresse.sin_addr.s_addr=inet_addr(ip);
        int longueur=sizeof(adresse);
     
    //creation du socket :
        int socketSiteHtml;
        if((socketSiteHtml=socket(AF_INET,SOCK_STREAM,0))<0){
        fprintf(stderr,"la socket a echouee\n");
        perror("ouverture socket");
        }
     
    //connexion au site distant :
        if(connect(socketSiteHtml,(struct sockaddr *) &adresse,longueur)==0)
            {
            printf("connexion réusie\n");
            }
        else
            {
            perror("Connexion");
            exit(EXIT_FAILURE);
            }
     
    //le message
        int taille_buffer=2000;
        char * message;
        message="GET /index.php HTTP/1.1\r\nHost:www.neuf.fr\r\n\r\n";
     
    //envoi de la requete
        if(send(socketSiteHtml,message,strlen(message)+1,0)==-1){
            perror("send");
            return EXIT_FAILURE;
            }
     
    //reception du message
        FILE * fi=NULL;
        char nomFichierHtml[10]="html.txt";
     
        if((fi=fopen(nomFichierHtml,"w+"))==NULL){
            perror("fopen");
            exit(EXIT_FAILURE);
        }
        ecrire(&socketSiteHtml,fi,taille_buffer);
     
    //lecture du fichier
        lecture(fi);
     
        fclose(fi);
        close(socketSiteHtml);
    return 0;
    }
     
    void lecture(FILE *fichier){
        rewind(fichier);
        int curseur=0;
        curseur=fgetc(fichier);
        while(curseur!=EOF){
            printf("%c",curseur);
            curseur=fgetc(fichier);
        }
    }
     
    void ecrire(int * socket,FILE * fichier,int taille){
        char buffer[taille];
        int octets_recus=0;
        int fin=0;
     
        while(fin==0){
            memset(buffer,0,taille);
            octets_recus=recv(*socket,buffer,taille,0);
            if(octets_recus<0){
                perror("recv");
                exit(EXIT_FAILURE);
            }
            if(octets_recus>0){
                printf("octets recus : %i\n",octets_recus);
                fputs(buffer,fichier);
            }
            if(octets_recus==0){
                fin=1;        
                }
        }
    }
    En tout cas, merci encore de tous vos conseils ! Je vous souhaite un bon WE, et si vous avez encore de bons conseils, je suis toujours preneur !

    PS : en fait, je me rends compte que certainement il faudrait que je créé une fonction de création de socket avec la connexion pour vraiment être efficace...

  12. #12
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 684
    Points : 30 973
    Points
    30 973
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par figarojuju Voir le message
    Bonjour,
    j'ai créé des fonctions simples pour un peu de modularité...ça commence à ressembler à du code un peu construit quand même !
    Tout à fait. C'est un code qui fait plaisir à lire.

    Citation Envoyé par figarojuju Voir le message
    PS : en fait, je me rends compte que certainement il faudrait que je créé une fonction de création de socket avec la connexion pour vraiment être efficace...
    Tu commences à comprendre l'idée. Essayer d'avoir de toutes petites fonctions très simples que tu peux réutiliser un peu partout avec divers paramètres de travail plutôt que de grosses locomotives qui ne seront appelées qu'une seule fois.

    Par exemple ce matin je lisais la doc d'une librairie de gestion de strings => http://cstr.sourceforge.net/docs/fr/...oc-fr-230.html

    Il y a des dizaines de petites fonctions qui font une tâche précise mais que tu peux utiliser de partout...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

Discussions similaires

  1. Taille de buffer dépassé pour DBMS_LOB
    Par Loizo dans le forum PL/SQL
    Réponses: 10
    Dernier message: 09/02/2009, 17h34
  2. Réponses: 39
    Dernier message: 27/03/2007, 20h25
  3. Réponses: 10
    Dernier message: 15/03/2005, 10h31
  4. [JTable] ajuster la taille d'une colonne à la taille du texte
    Par GETah dans le forum Agents de placement/Fenêtres
    Réponses: 3
    Dernier message: 24/02/2005, 11h53
  5. buffer pour fichier
    Par Bug's Bunny dans le forum C
    Réponses: 6
    Dernier message: 11/06/2004, 13h21

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