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 :

Calcul, socket !


Sujet :

Réseau C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 23
    Par défaut Calcul, socket !
    bonjour tout le monde !

    J'ai comme projet de faire un programme répartissant des calculs sur plusieurs ordinateurs. J'ai fait un programme client et un programme serveur (pour l'instant aucune donnée ne transite entre les deux, c'est un simple test de niveau très basique).

    Mon problème est le suivant: cela marche lorsque je démarre le client et le server sur mon ordi (en localhost) mais j'aimerais rendre cela possible en démarrant le server sur mon ordi et le client sur un autre ordi (voir plusieurs clients sur plusieurs ordi). Si quelqu'un avait une idée, merci d'avance !


    Code 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
    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
     
    #if defined (WIN32)
    #include <winsock2.h>
    #elif defined (linux)
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #define INVALID_SOCKET -1
    #define SOCKET_ERROR -1
    #define closesocket(s) close (s)
    typedef int SOCKET;
    typedef struct sockaddr_in SOCKADDR_IN;
    typedef struct sockaddr SOCKADDR;
    #endif
    #include <stdio.h>
    #include <stdlib.h>
    int main (void)
    {
        #if defined (WIN32)
            WSADATA WSAData;
            int erreur = WSAStartup(MAKEWORD(2,0), &WSAData);
        #else
            int erreur = 0;
        #endif
        SOCKADDR_IN sin = {0};
        SOCKET sock;
        int recsize = (int) sizeof sin;
        int sock_err;
        if(!erreur)
        {
            // Création d'une socket
            sock = socket (AF_INET, SOCK_STREAM, 0);
            // Si la socket est valide
            if (sock != INVALID_SOCKET)
            {
                printf ("La socket %d est maintenant ouverte en mode TCP/IP\n", sock);
                // Configuration
                sin.sin_addr.s_addr = *(IN_ADDR *)(INADDR_ANY);   // Adresse IP automatique
                sin.sin_family = AF_INET;              // protocol familial (IP)
                sin.sin_port = htons (23);       // listage du port
                sock_err = bind (sock, (SOCKADDR *) &sin, recsize);
                //Si la socket fonctionne
                if (sock_err != SOCKET_ERROR)
                {
                    // démarrage du listage (mode server)
                    sock_err = listen (sock, 5);
                    printf ("Listage du port %d...\n", 23);
                    //Si la socket fonctionne
                    if (sock_err != SOCKET_ERROR)
                    {
                        // Attente pendant laquelle le client se connecte
                        printf ("Patientez pendant que le client se connecte sur le port %d...\n", 23);
                        sock = accept (sock, (SOCKADDR *) &sin, &recsize);
                        printf ("Un client se connecte avec la socket %d de %s:%d\n", sock, inet_ntoa (sin.sin_addr), htons (sin.sin_port));
                        system("pause");
                    }
                }
                // fermeture de la socket
                printf ("Fermeture de la socket\n");
                closesocket(sock);
                printf ("Fermeture du serveur terminée\n");
            }
            #if defined (WIN32)
                WSACleanup();
            #endif
        }
        return EXIT_SUCCESS;
    }






    code du 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
    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
     
    #if defined (WIN32)
    #include <winsock2.h>
    #elif defined (linux)
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #define INVALID_SOCKET -1
    #define SOCKET_ERROR -1
    #define closesocket(s) close (s)
    typedef int SOCKET;
    typedef struct sockaddr_in SOCKADDR_IN;
    typedef struct sockaddr SOCKADDR;
    #endif
    #include <stdio.h>
    #include <stdlib.h>
    int main (void)
    {
        #if defined (WIN32)
            WSADATA WSAData;
            int erreur = WSAStartup(MAKEWORD(2,0), &WSAData);
        #else
            int erreur = 0;
        #endif
        SOCKET sock;
        SOCKADDR_IN sin;
        char buffer[512] = "";
        int i;
     
        if(!erreur)
        {
            // Création de la socket
            sock = socket(AF_INET, SOCK_STREAM, 0);
            // Configuration de la connexion
            sin.sin_addr.s_addr = inet_addr("127.0.0.1");
            sin.sin_family = AF_INET;
            sin.sin_port = htons(23);
            // Si le client arrive à se connecté
            if(connect(sock, (SOCKADDR *)&sin, sizeof(sin)) != SOCKET_ERROR)
                {
                  printf("Connexion à %s sur le port %d\n", inet_ntoa (sin.sin_addr), htons(sin.sin_port));
                  system("pause");
                }
            else
                printf("Impossible de se connecter\n");
            // On ferme la socket précédemment ouverte
            closesocket(sock);
            #if defined (WIN32)
                WSACleanup();
            #endif
        }
        return EXIT_SUCCESS;
    }


    edit: même en remplacant 127.0.0.1 par l'ip de mon ordi dans le code du client, le client n'arrive pas à se connecter à mon ordi

  2. #2
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    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 395
    Par défaut
    Commence par faire un telnet du client vers ton serveur, pour savoir si le bug peut venir du client ou non.
    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
    Membre averti
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 23
    Par défaut
    comment faire ? (et les pc doivent-ils être reliés d'une quelquonque manière ? ou suffit-ils qu'ils soient connectés au net ?)
    merci d'avance

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 23
    Par défaut
    J'ai réglé mon problème mais un j'en ai un nouveau:

    Comment faire pour que plusieurs clients puissent se connecter à mon serveur ?
    (le serveur doit à tout pri faire la distinction entre les différents clients pour l'envoie des informations).

    Concretement, voilà le principe:
    Trois clients se connectent au serveur. Il y a mettons 50000 informations à traiter, le serveur envoie la première au client1, la seconde au client2 et la troisieme au client3.
    Dès que le client a traiter l'information, le serveur lui en renvoie une et ainsi de suite jusqu'à 50 000.

    Merci d'avance

  5. #5
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Darktrouble Voir le message
    Mon problème est le suivant: cela marche lorsque je démarre le client et le server sur mon ordi (en localhost) mais j'aimerais rendre cela possible en démarrant le server sur mon ordi et le client sur un autre ordi (voir plusieurs clients sur plusieurs ordi). Si quelqu'un avait une idée, merci d'avance !
    Ceci est étrange :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    sin.sin_addr.s_addr = *(IN_ADDR *)(INADDR_ANY);   // Adresse IP automatique
    (d'ailleurs, ça ne compile pas)...

    J'aurais mis

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    /* automatic IP address */
             sin.sin_addr.s_addr = htonl (INADDR_ANY);
    Avec cette correction, ça fonctionne
    • Sur la même machine :
      • Par la boucle (127.0.0.1)
      • Par l'IP réseau (192.168.0.5)
    • Entre 2 machines (192.168.0.5 <-> 192.168.0.4)

    Pour faire un serveur multi-clients, le plus simple est d'utiliser les threads...

    http://emmanuel-delahaye.developpez.com/reseaux.htm
    http://emmanuel-delahaye.developpez.com/pthreads.htm

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    23
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 23
    Par défaut
    Merci bien, j'avais oublié de corriger l'erreur.

    J'ai trouvé une solution pour éviter le multithreading qui semble me convenir!
    Mais je rencontre de nouveau un soucis. Mon serveur transmet des très grands nombres aux clients. Ces grands nombres sont déclarés grace à une biblio de gestion de grands nombres (GMP) de la manière suivante:

    mpz_t nombre;

    (j'imagine que ceux-ci sont stockés dans des structures ...).

    Le problème est que quand le client reçoit ce nombre et que je lui fait afficher, il m'affiche nimporte quoi, aucun rapport avec le nombre transmit. Je vous met ici le code important :


    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
     
                    while(x)
                    {
                        if (sock_err != SOCKET_ERROR)
                        {
                            // Attente pendant laquelle le client se connecte
                            printf ("Patientez pendant que les clients se connectent sur le port %d...\n", 23);
                            sock = accept (sock, (SOCKADDR *) &sin, &recsize);
                            x=0;
                            printf ("Un client se connecte avec la socket %d de %s:%d\n", sock, inet_ntoa (sin.sin_addr), htons (sin.sin_port));
                            sock_err = send(sock, &i[0], sizeof(mpz_t), 0); // Comme il y a deux clients et deux nombres, les nombres sont respectivement stockés dans i[0] et i[1]
                        }
                    }
     
                    while(y)
                    {
                        if (sock_err2 != SOCKET_ERROR)
                        {
                            // Attente pendant laquelle le client se connecte
                            printf ("Patientez pendant que les clients se connectent sur le port %d...\n", 24);
                            sock2 = accept (sock2, (SOCKADDR *) &sin2, &recsize2);
                            y=0;
                            printf ("Un client se connecte avec la socket %d de %s:%d\n", sock2, inet_ntoa (sin2.sin_addr), htons (sin2.sin_port));
                            sock_err2 = send(sock2, i[1], sizeof(i[1]), 0);
     
     
                        }

    (on remarque deux méthodes différentes d'envoi pour le client 1 et client 2, c'est parce que je suis tellement désesperé que je test toutes les possibilités ^^)).

    La réception se fait de la même manière que pour le send();

    et l'affichage du nombre reçut se faire comme ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    gmp_printf("%Zd\n", &i[0]); //fonction propre à la librairie GMP
    J'ai également essayé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    gmp_printf("%Zd\n", i[0]);
    mais rien ne veut! (i[0] étant bien déclaré dans mon client).



    Merci d'avance

Discussions similaires

  1. Réponses: 1
    Dernier message: 24/01/2011, 10h44
  2. executer une application a distance : Sockets ? RPC ? CORBA?
    Par a_hic dans le forum Développement
    Réponses: 5
    Dernier message: 30/05/2006, 13h02
  3. [TP7] Calculer sin, cos, tan, sqrt via le FPU
    Par zdra dans le forum Assembleur
    Réponses: 8
    Dernier message: 25/11/2002, 04h09
  4. Algo de calcul de FFT
    Par djlex03 dans le forum Traitement du signal
    Réponses: 15
    Dernier message: 02/08/2002, 17h45
  5. transfert d'un fichier bitmap en socket tcp
    Par localhost dans le forum C++Builder
    Réponses: 5
    Dernier message: 29/07/2002, 00h40

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