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

Threads & Processus C++ Discussion :

utilisation de socket


Sujet :

Threads & Processus C++

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 7
    Par défaut utilisation de socket
    Bonjour,
    je souhaiterais faire passer des informations d'un ordinateur A a un ordinateur B par le reseau internet. J'ai donc fait des recherche et je suis arriver au sujet des sockets, je ne connaissais méme pas se mot avant ...
    je programme en c++, je ne suis pas un cador mais j'ai quelques notion avec lesquels j'arrive a me débrouiller.
    j'ai donc chercher a réaliser un socket en c++, grace a se site j'ai trouver de quoi faire un bon début.
    http://c.developpez.com/cours/socket...p-demystifies/
    j'ai donc réaliser deux programme différent, un pour le serveur et l'autre pour le client voila se que sa donne.
    client
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    WSADATA WSAData; //initialisation WSADATA utilisée pour le démarrage de WSAStartup()
    WSAStartup(MAKEWORD(2,0), &WSAData); // permet de dire à l'ordinateur que vous allez utiliser des sockets
    //Création du socket
    SOCKET sock; // init de la variable sock type socket
    SOCKADDR_IN sin; //SOCKADDR contient les informations techniques du socket
    sin.sin_addr.s_addr = inet_addr("adresse IP de mon PC A"); //adresse du serveur
    sin.sin_family = AF_INET; //type de socket
    sin.sin_port = htons(23); //utilisation du port telnet
    sock = socket(AF_INET,SOCK_STREAM,0); //création su socket ( STREAM aprés il faut faire accept() ou de connect() et pas DGRAM)
    bind(sock, (SOCKADDR *)&sin, sizeof(sin)); //attache le socket directement au port et à l'adresse
    //connection avec le serveur
    connect(sock, (SOCKADDR *)&sin, sizeof(sin)); //permet de se connecter
    send(sock, "Ceci est un test!\r\n", 19, 0); //envoi d'un string de 19 caracteres
    closesocket(sock); // ferme le socket

    WSACleanup(); //nettoyage WSA
    }
    serveur

    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    WSADATA WSAData; //initialisation WSADATA utilisée pour le démarrage de WSAStartup()
    WSAStartup(MAKEWORD(2,0), &WSAData); // permet de dire à l'ordinateur que vous allez utiliser des sockets

    SOCKET sock; // init de la variable sock type socket
    SOCKADDR_IN sin; //SOCKADDR contient les informations techniques du socket
    sin.sin_addr.s_addr = htonl(INADDR_ANY); //adresse du serveur se pc (A)
    sin.sin_family = AF_INET; //type de socket
    sin.sin_port = htons(23); //utilisation du port telnet
    sock = socket(AF_INET,SOCK_STREAM,0); //création su socket ( STREAM aprés il faut faire accept() ou de connect() et pas DGRAM)
    bind(sock, (SOCKADDR *)&sin, sizeof(sin)); //attache le socket directement au port et à l'adresse

    listen(sock, 0); //scrutation du port du socket, Le 1er paramètre, sock, est le socket sur lequel le listen() écoutera. Le 2ème paramètre s'appelle le BACKLOG. C'est le nombre maximum de connexions qui seront écoutées en même temps.
    int val = 0; //déclaration d'une variable, utiliser pour le retour de accept, vérification du socket
    while(CheckBox1->Checked==FALSE ) //boucle
    {
    int sizeof_sin = sizeof(sin); //définition de la taille du socket
    val = accept(sock, (SOCKADDR *)&sin, &sizeof_sin); //permet d'accepter une connexion 1er paramètre : le socket. Le 2ème paramètre est votre SOCKADDR_IN que vous avez créé pour prendre les informations du client connecté sur votre serveur. Le 3ème et dernier paramètre est un pointeur vers la variable qui va recevoir le nombre d'octets écrits dans votre SOCKADDRIN. La variable doit être initialisée avec la taille de cette structure.
    if(val != INVALID_SOCKET) //vérification de "validité" du socket
    { // Fonctions à éxécuter sur le socket.
    Label1->Caption="reçu";
    }
    }

    closesocket(sock); //fermeture du socket
    WSACleanup(); //nettoyage WSA

    }
    mais je ne reçoi absolument rien ou alors je ne sais pas lire mais une chose est sur je ne change jamais le caption de mon label.
    J'ai fait du pas a pas pour voir lors de la commande connect() une bonne 10en de secondes s'écoule avant de passer a la ligne suivante, idem pour la commande accept().
    alors je ne sais pas trop se que j'ai mal fait et je ne sais pas trop vers qui me tourner.
    J'espére avoir clairement exposer mon probléme et je vous remerci de prendre quelques instants pour lire ceci et peut étre y répondre.

    Cordialement
    Charléne

  2. #2
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 463
    Par défaut
    Port 23.
    Vous avez toutes les chances de vous faire rembarrer par le firewall.

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 7
    Par défaut
    bonjour bacelar,
    Lors de l'éxécution de mon programme le pc m'informe qu'un programme veut faire je sais plus quoi, j'ai donc configurer mon pare-feu

  4. #4
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 463
    Par défaut
    J'ai pris la peine de lire le code.

    Le problème n'a rien à voir avec les sockets.

    Vous modifiez le titre de votre label, en espérant que cela se fasse dans le thread qui a créé le label ou que la primitive "Caption" soit thread-safe.

    OK, mais pour que cela soit visible, il faut que votre fenêtre se réaffiche, chose qu'elle ne fait que sur le traitement d'un message WM_PAINT.
    Votre boucle active sur "CheckBox1->Checked==FALSE" vous empêche de lire les messages de fenêtre.

    Je vous conseil donc de ne pas faire votre boucle dans le thread d'affichage mais dans un thread de travail qui n'accèdera pas directement aux contrôles (pas de Label1 ni de CheckBox1) mais dialoguera avec le thread d'affichage via des PostMessages sur l'une des fenêtres gérées par le thread d'affichage.

    Multithreading

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 7
    Par défaut
    Bonjour bacelar,
    j'ai complétement refait mon code j'ai mis des test a chaque étape pour vérifier et trouver ou est le probléme, c'est un peut long mais c'était nécessaire.
    voila se que sa donne
    client
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    // ****************************** **************************
    // Déclaration des variables
    // ****************************** **************************

    WSADATA initialisation_win32; // Variable permettant de récupérer la structure d'information sur l'initialisation
    int erreur; // Variable permettant de récupérer la valeur de retour des fonctions utilisées
    SOCKET sock; // init de la variable sock type socket
    int tempo; // Variable temporaire de type int
    SOCKADDR_IN information_sur_la_source; // Déclaration de la structure des informations lié à l'écoute
    SOCKADDR_IN information_sur_la_destination ; // Déclaration de la structure des informations lié au serveur
    int nombre_de_caractere; // Indique le nombre de caractères qui a été reçu ou envoyé
    char buffer[65535]; // Tampon contenant les données reçues ou envoyées
    char adresse_serveur [13];
    strcpy(adresse_serveur,"aa.bb. cc.ddd");

    // ****************************** **************************
    // Initialisation de Winsock
    // ****************************** **************************

    erreur=WSAStartup(MAKEWORD(2,2 ),&initialisation_win32);
    Memo1->Clear();
    if (erreur!=0)
    {
    Memo1->Lines->Add("Desole, je ne peux pas initialiser Winsock");
    }
    else
    {
    Memo1->Lines->Add("\nInitialisation de Winsock OK");
    }

    // ****************************** **************************
    // Ouverture d'une Socket
    // ****************************** **************************

    sock = socket(AF_INET,SOCK_STREAM,0); //création su socket ( STREAM aprés il faut faire accept() ou de connect() et pas DGRAM)
    if (sock==INVALID_SOCKET) //test de la validité de la socket
    {
    Memo1->Lines->Add("\nDesole, je ne peux pas creer la socket");
    }
    else
    {
    Memo1->Lines->Add("\nCréation de la socket OK");
    }

    // ****************************** **************************
    // Activation de l'option permettant d'activer l'algorithme de Nagle
    // ****************************** **************************

    tempo=1;
    erreur=setsockopt(sock,IPPROTO _TCP,TCP_NODELAY,(char *)&tempo,sizeof(tempo));
    if (erreur!=0)
    {
    Memo1->Lines->Add("\nDesole, je ne peux pas configurer cette option");
    }
    else
    {
    Memo1->Lines->Add("\nConfiguration des options OK");
    }

    // ****************************** **************************
    // Ouverture de la session TCP sur destination de l'adresse IP aa.bb.cc.dd et du port xx
    // ****************************** **************************

    information_sur_la_destination .sin_family=AF_INET;
    information_sur_la_destination .sin_addr.s_addr=inet_addr(buf fer); // Indiquez l'adresse IP de votre serveur
    information_sur_la_destination .sin_port=htons(23); // Port écouté du serveur (23)
    erreur=connect(sock,(struct sockaddr*)&information_sur_la_ destination,sizeof(information _sur_la_destination));
    if (erreur!=0)
    {
    Memo1->Lines->Add("\nDesole, je n'ai pas pu ouvrir la session TCP" );
    }
    else
    {
    Memo1->Lines->Add("\nOuverture de session TCP OK");
    }

    // ****************************** **************************
    // Envoi des données
    // ****************************** **************************

    strcpy(buffer,"Ceci est un test, pourvu que cela fonctionne je commence a en avoir ..."); // Copie la chaine de caractère dans buffer
    nombre_de_caractere=send(sock, buffer,strlen(buffer),0);
    if (nombre_de_caractere==SOCKET_E RROR)
    {
    Memo1->Lines->Add("\nDesole, je n'ai pas envoyer les données");
    }
    else
    {
    Memo1->Lines->Add("\nEnvoi des données OK");
    }

    // ****************************** **************************
    // Fermeture de la session TCP Correspondant à la commande connect()
    // ****************************** **************************

    erreur=shutdown(sock,2); // 2 signifie socket d'émission et d'écoute
    if (erreur!=0)
    {
    Memo1->Lines->Add("\nDesole, je ne peux pas fermer la session TCP");
    }
    else
    {
    Memo1->Lines->Add("\nFermeture de session TCP");
    }

    // ****************************** **************************
    // Fermeture de la socket correspondant à la commande socket()
    // ****************************** **************************

    erreur=closesocket(sock);
    if (erreur!=0)
    {
    Memo1->Lines->Add("\nDesole, je ne peux pas liberer la socket");
    }
    else
    {
    Memo1->Lines->Add("\nFermeture de la socket OK");
    }

    // ****************************** **************************
    // Quitte proprement le winsock ouvert avec la commande WSAStartup
    // ****************************** **************************

    erreur=WSACleanup(); // A appeler autant de fois qu'il a été ouvert.
    if (erreur!=0)
    {
    Memo1->Lines->Add("\nDesole, je ne peux pas liberer winsock");
    }
    else
    {
    Memo1->Lines->Add("\nQuitte winsock OK");
    }
    coté serveur
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {

    // ****************************** **************************
    // Déclaration des variables
    // ****************************** **************************

    WSADATA initialisation_win32; // Variable permettant de récupérer la structure d'information sur l'initialisation
    int erreur; // Variable permettant de récupérer la valeur de retour des fonctions utilisées
    SOCKET sock; // init de la variable sock type socket
    int tempo; // Variable temporaire de type int
    SOCKADDR_IN information_sur_la_source; // Déclaration de la structure des informations lié à l'écoute
    SOCKET id_de_la_nouvelle_socket; // Identifiant de la nouvelle socket
    int nombre_de_caractere; // Indique le nombre de caractères qui a été reçu ou envoyé
    char buffer[65535]; // Tampon contenant les données reçues ou envoyées

    // ****************************** **************************
    // Initialisation de Winsock
    // ****************************** **************************

    erreur=WSAStartup(MAKEWORD(2,2 ),&initialisation_win32);
    Memo1->Clear();
    if (erreur!=0)
    {
    Memo1->Lines->Add("Desole, je ne peux pas initialiser Winsock");
    }
    else
    {
    Memo1->Lines->Add("\nInitialisation de Winsock OK");
    }

    // ****************************** **************************
    // Ouverture d'une Socket
    // ****************************** **************************

    sock = socket(AF_INET,SOCK_STREAM,0); //création su socket ( STREAM aprés il faut faire accept() ou de connect() et pas DGRAM)
    if (sock==INVALID_SOCKET) //test de la validité de la socket
    {
    Memo1->Lines->Add("\nDesole, je ne peux pas creer la socket");
    }
    else
    {
    Memo1->Lines->Add("\nCréation de la socket OK");
    }

    // ****************************** **************************
    // Activation de l'option permettant d'activer l'algorithme de Nagle
    // ****************************** **************************

    tempo=1;
    erreur=setsockopt(sock,IPPROTO _TCP,TCP_NODELAY,(char *)&tempo,sizeof(tempo));
    if (erreur!=0)
    {
    Memo1->Lines->Add("\nDesole, je ne peux pas configurer cette option");
    }
    else
    {
    Memo1->Lines->Add("\nConfiguration des options OK");
    }

    // ****************************** **************************
    // Lie la socket à une ip et un port d'écoute
    // ****************************** **************************

    information_sur_la_source.sin_ family=AF_INET;
    information_sur_la_source.sin_ addr.s_addr=INADDR_ANY; // Ecoute sur toutes les IP locales
    information_sur_la_source.sin_ port=htons(23); // Ecoute sur le port 23
    erreur=bind(sock,(struct sockaddr*)&information_sur_la_ source,sizeof(information_sur_ la_source));
    if (erreur!=0)
    {
    Memo1->Lines->Add("\nDesole, je ne peux pas ecouter ce port");
    }
    else
    {
    Memo1->Lines->Add("\nEcoute du port OK");
    }

    // ****************************** **************************
    // Attente d'ouverture de session
    // ****************************** **************************

    erreur=99; // Initiation de erreur pour être sur que l'on va rentrer dans la boucle
    while(erreur!=0) // Boucle tant qu'une demande de session (SYN) tcp n'a pas été reçu
    {
    erreur=listen(sock,1);
    Memo1->Lines->Add("\nattente d'établicement de session TCP");
    }
    Memo1->Lines->Add("Une session TCP a été établie");

    // ****************************** **************************
    // Acceptation de la demande d'ouverture de session
    // ****************************** **************************

    tempo=sizeof(information_sur_l a_source); // Passe par une variable afin d'utiliser un pointeur
    id_de_la_nouvelle_socket=accep t(sock,(struct sockaddr*)&information_sur_la_ source,&tempo);
    if(id_de_la_nouvelle_socket==I NVALID_SOCKET)
    {
    Memo1->Lines->Add("\nDesole, je ne peux pas accepter la session TCP");
    }
    else
    {
    Memo1->Lines->Add("\nsession TCP OK");
    }

    // ****************************** **************************
    // Reception des données
    // ****************************** **************************

    nombre_de_caractere=recv(id_de _la_nouvelle_socket,buffer,151 5,0);
    if (nombre_de_caractere==SOCKET_E RROR)
    {
    Memo1->Lines->Add("\nDesole, je n'ai pas recu de donnee");
    }
    else
    {
    buffer[nombre_de_caractere]=0; // Permet de fermer le tableau après le contenu des data, car la fonction recv ne le fait pas
    Memo1->Lines->Add("\nVoici les donnees : ");
    Memo1->Lines->Add(buffer);
    }

    // ****************************** **************************
    // Fermeture de la session TCP Correspondant à la commande connect()
    // ****************************** **************************

    erreur=shutdown(sock,2); // 2 signifie socket d'émission et d'écoute
    if (erreur!=0)
    {
    Memo1->Lines->Add("\nDesole, je ne peux pas fermer la session TCP");
    }
    else
    {
    Memo1->Lines->Add("\nFermeture de session TCP");
    }

    // ****************************** **************************
    // Fermeture de la socket correspondant à la commande socket()
    // ****************************** **************************

    erreur=closesocket(sock);
    if (erreur!=0)
    {
    Memo1->Lines->Add("\nDesole, je ne peux pas liberer la socket");
    }
    else
    {
    Memo1->Lines->Add("\nFermeture de la socket OK");
    }

    // ****************************** **************************
    // Quitte proprement le winsock ouvert avec la commande WSAStartup
    // ****************************** **************************

    erreur=WSACleanup(); // A appeler autant de fois qu'il a été ouvert.
    if (erreur!=0)
    {
    Memo1->Lines->Add("\nDesole, je ne peux pas liberer winsock");
    }
    else
    {
    Memo1->Lines->Add("\nLiberation de winsock OK");
    }
    donc coté serveur sur le memo on a : Une session TCP a été établie, je suis donc bloqué a accept() enfin en attente de client.
    coté client je n'ai pas réussi a ouvrir une session TCP
    voila le memo

    Initialisation de Winsock OK
    Création de la socket OK
    Configuration des options OK
    Desole, je n'ai pas pu ouvrir la session TCP
    Desole, je n'ai pas envoyer les données
    Desole, je ne peux pas fermer la session TCP
    Fermeture de la socket OK
    Quitte winsock OK

    J'ai donc un probléme avec mon connect()
    Es ce un probléme de code, de matériel, de port enfin je ne sais pas aider moi svp

    Amicalement
    Charléne

  6. #6
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 463
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    erreur=connect(sock,(struct sockaddr*)&information_sur_la_ destination,sizeof(information _sur_la_destination));
    Un petit GetLastError, SVP, pour avoir l'erreur.

  7. #7
    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
    J'ai l'impression que l'erreur se situe ici dans 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
    char buffer[65535]; // Tampon contenant les données reçues ou envoyées
    char adresse_serveur [13];
    strcpy(adresse_serveur,"aa.bb. cc.ddd");
    ...
    information_sur_la_destination .sin_family=AF_INET;
    information_sur_la_destination .sin_addr.s_addr=inet_addr(buf fer); // Indiquez l'adresse IP de votre serveur
    information_sur_la_destination .sin_port=htons(23); // Port écouté du serveur (23)
    erreur=connect(sock,(struct sockaddr*)&information_sur_la_ destination,sizeof(information _sur_la_destination));
    if (erreur!=0)
    {
    Memo1->Lines->Add("\nDesole, je n'ai pas pu ouvrir la session TCP" );
    }
    else
    {
    Memo1->Lines->Add("\nOuverture de session TCP OK");
    }
    buffer n'est pas initialisé et en plus, j'ai l'impression que c'est plutôt la variable adresse_serveur qu'il faut utiliser.

    Ceci ne doit pas compiler car il y a un espace entre buf et fer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    information_sur_la_destination .sin_addr.s_addr=inet_addr(buf fer);
    Ce plus, buffer n'est pas initialisé et en plus, j'ai l'impression que c'est plutôt la variable adresse_serveur qu'il faut utiliser.

    Au fait, dans strcpy(adresse_serveur,"aa.bb. cc.ddd"); l'adresse aa.bb. cc.ddd n'est pas valide mais je suppose que c'est uniquement pour poster le forum, dans le vrai code, il y a une vraie adresse (attention toutefois aux espaces superflus).

    Le bon 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
    char buffer[65535]; // Tampon contenant les données reçues ou envoyées
    char adresse_serveur [13];
    strcpy(adresse_serveur,"192.168.1.1"); // ou autre adresse
    ...
    information_sur_la_destination .sin_family=AF_INET;
    information_sur_la_destination .sin_addr.s_addr=inet_addr(adresse_serveur); // Indiquez l'adresse IP de votre serveur
    information_sur_la_destination .sin_port=htons(23); // Port écouté du serveur (23)
    erreur=connect(sock,(struct sockaddr*)&information_sur_la_ destination,sizeof(information _sur_la_destination));
    if (erreur!=0)
    {
    Memo1->Lines->Add("\nDesole, je n'ai pas pu ouvrir la session TCP" );
    }
    else
    {
    Memo1->Lines->Add("\nOuverture de session TCP OK");
    }
    Un petit effort dans la présentation du code SVP (respect de l'indentation), cela facilitera la lecture.

    De plus, pour le code, c'est la balice [code][/code] qu'il faut utiliser et pas la balise [quote][/quote]
    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
    .

Discussions similaires

  1. [MFC] Faible utilisation des sockets via les MFC ?
    Par Yellowmat dans le forum MFC
    Réponses: 1
    Dernier message: 25/08/2005, 17h15
  2. récupérer l' IP du client lors d'utilisation de sockets
    Par zegota dans le forum Entrée/Sortie
    Réponses: 7
    Dernier message: 27/07/2005, 22h27
  3. [CF][PPC/VB.NET] Comment utiliser les Socket avec Pocket PC ?
    Par joefou dans le forum Windows Mobile
    Réponses: 5
    Dernier message: 17/05/2005, 14h24
  4. [MFC] Utilisation de sockets
    Par keupon dans le forum MFC
    Réponses: 2
    Dernier message: 28/01/2004, 14h37
  5. utilisation des sockets sous windows
    Par Tupac dans le forum Réseau
    Réponses: 2
    Dernier message: 21/12/2002, 18h24

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