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 :

Client / Serveur TCP/IP


Sujet :

Réseau C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Septembre 2008
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 48
    Par défaut Client / Serveur TCP/IP
    voila je souhaite creer un serveur et un client tcp/ip.
    pour l'instant mon client et mon serveur communique bien entre eux (un message est transmis entre le client et le serveur) mais je souhaite que mon client fasse des requetes HTTP ( a la place de la transmission de "salut"), et que le serveur reponde a ces requetes mais je ne sais pas trop comment faire.
    je vous donne ici le code de mon client et celui de mon serveur.
    merci d'avance pour votre aide tres precieuse.

    Mon 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
    56
    57
    58
    59
    60
    61
    62
    63
    64
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <netdb.h>
    #include <math.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;
    typedef struct hostent *HOSTENT;
     
     
     
    int main (int argc, char *argv[])
    {
     
          int i;
          SOCKET sock;
        SOCKADDR_IN sin;
        HOSTENT remote_host;
        char buffer[32] = "";
     
               /* Création de la socket */
            sock = socket(AF_INET, SOCK_STREAM, 0);
     
            /* Configuration de la connexion */
             sin.sin_family = AF_INET;
     
        if ((remote_host = gethostbyname(argv[1])) == (HOSTENT *) NULL )
        {
            fprintf( stderr, "%s: unknown host: %s\n",argv[0], argv[1]);
            exit(__LINE__);
        }
     
        (void) bcopy( (char *)remote_host->h_addr, (char *) &sin.sin_addr,
    remote_host->h_length );
        sin.sin_port = htons(atoi(argv[2]));
     
            /* 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));
                /* Si l'on reçoit des informations : on les affiche à l'écran */
                if(recv(sock, buffer, 32, 0) != SOCKET_ERROR)
                    printf("Recu : %s\n", buffer);
                }
            else
                printf("Impossible de se connecter\n");
     
     
     
            /* On ferme la socket précédemment ouverte */
            closesocket(sock);
     
     
        return EXIT_SUCCESS;
    }
    Mon 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
    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
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.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;
     
     
     
    int main(int argc, char *argv[])
    {
     
        //Socket et contexte d'adressage du serveur
        SOCKADDR_IN sin;
        SOCKET sock;
        char buffer[32];
        unsigned int recsize = (unsigned int) sizeof sin;
     
        // Socket et contexte d'adressage du client 
        SOCKADDR_IN csin;
        SOCKET csock;
        unsigned int crecsize = (unsigned int) sizeof csin;
     
        int sock_err;
        char buf[BUFSIZ];
        int read_ret;
     
               /* 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 = htonl(INADDR_ANY);  /* Adresse IP automatique */
                sin.sin_family = AF_INET;                 /* Protocole familial (IP) */
                sin.sin_port = 0 ;               /* 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) */
                    if ( getsockname(sock,(SOCKADDR *) &sin,(int*)&recsize ) < 0 )
                    {
                    char s[BUFSIZ];
                    sprintf( s, "%s: can't get port number of socket (%d)",        argv[0], sock );
                    perror(s);
                    exit(__LINE__);
                        }
     
                   sock_err = listen(sock, 5);
                    printf("Listage du port %d...\n",ntohs(sin.sin_port));
     
                    /* 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", ntohs(sin.sin_port));
                        csock = accept(sock, (SOCKADDR *) &csin, &crecsize);
                        printf("Un client se connecte avec la socket %d de %s:%d\n",
    csock, inet_ntoa(csin.sin_addr), htons(csin.sin_port));
     
     
                    sock_err = send(csock, buffer, 32, 0);
     
                        if(sock_err != SOCKET_ERROR)
                            printf("Chaine envoyée : %s\n", buffer);
                        else
                            printf("Erreur de transmission\n");
     
                     }
                     /* Il ne faut pas oublier de fermer la connexion (fermée dans les deux sens) */
                        shutdown(csock, 2);
     
     
                    }
                    else
                        perror("listen");
                }
                else
                    perror("bind");
     
                while ( (read_ret = read( csock, buf, sizeof buf )) > 0 )
                {
                    buf[read_ret]='\0';
                    printf( "%s", buf ); 
                }
     
             if (read_ret == 0) {
              printf( "%s: connection closed by distant peer:\n", argv[0] );
                }
     
        if ( read_ret < 0 ) {
            char s[BUFSIZ];
            sprintf( s, "%s: error reading socket", argv[0] );
            perror(s);
            exit(__LINE__);
        } 
     
     
     
     
                /* Fermeture de la socket client et de la socket serveur */
                printf("Fermeture de la socket client\n");
                closesocket(csock);
                 printf("Fermeture de la socket serveur\n");
                closesocket(sock);
                printf("Fermeture du serveur terminée\n");
            }
     
            else
                perror("socket");
     
        return EXIT_SUCCESS;
    }

  2. #2
    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
    Globalement, tu veux implémenter le protocole HTTP sur ton client et ton serveur.

    Première action : lire les RFC sur HTTP RFC 1945 et RFC 2616
    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
    .

  3. #3
    Membre averti
    Inscrit en
    Septembre 2008
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 48
    Par défaut
    désolé mais je ne suis vraiment pas fort en anglais, ce qu'il me manque c'est surtout le code pour une requete tel que get, head....et le code du serveur pour repondre a la requete...

  4. #4
    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
    C'est pas si simple. Les 2 liens des RFC définissent le protocole HTTP. Si la somme de ces 2 RFC fait plus de 200 pages, c'est que le protocole n'est pas simple (j'oserais, je dirais que c'est un des plus complexes d'Internet actuellement).

    Il n'est tout simplement pas possible de te donner une requête sans te demander de lire ces RFC.

    Ici, les traductions en francais de ces RFC (que tu aurais pu trouver par toi même ). Attention, ce ne sont que des traductions, cela ne vaut pas l'original

    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
    .

  5. #5
    Membre averti
    Inscrit en
    Septembre 2008
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 48
    Par défaut
    merci beaucoup pour ta réponse.je vais lire tous ça et te reposerai des questions pour y voir un peu plus clair.

  6. #6
    Membre averti
    Inscrit en
    Septembre 2008
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 48
    Par défaut
    une petite question avant de me lancer dans la lecture des protocoles, peut tu me définir ce qu'est un appel POSIX sous linux ?

  7. #7
    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 KaNDeL Voir le message
    voila je souhaite creer un serveur et un client tcp/ip.
    pour l'instant mon client et mon serveur communique bien entre eux (un message est transmis entre le client et le serveur)
    Non. Ton code d'emission/réception des messages est faux. Ce qui est trompreur, c'est qu'ici, le cas est simple et que de plus, tu as écrit le client et le serveur (les erreurs sont compatibles entre elles). Dans la vraie vie, on ne transmet pas de 0 en ligne en mode texte.

    Avant d'implémenter quoi que ce soit de plus, tu dois absolument apprendre à gérer les échanges de texte correctement :

    http://emmanuel-delahaye.developpez....reseaux-c/#LIV

    et corriger ton code en conséquence...

  8. #8
    Membre averti
    Inscrit en
    Septembre 2008
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 48
    Par défaut
    je ne comprend pas ce que signifie "on ne transmet pas de 0 en ligne". merci

  9. #9
    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 KaNDeL Voir le message
    je ne comprend pas ce que signifie "on ne transmet pas de 0 en ligne". merci
    Une chaine C comporte au moins un 0 en fin chaine.

    Les protocoles texte ne s'attendent pas à recevoir ce 0. (les commandes étant généralement des lignes de textes, ils s'attendent plutôt à "\n", "\r\n" c'est à dire de fin de lignes...

    Donc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    char s[32] = "";
     
    strcpy(s, "hello world");
    send(sock, s, sizeof s, 0);
    est incorrect, car c'est un bloc de 32 octets terminé par des 0 qui va être émis.

    - Les 0 peuvent perturber le protocole du receveur (comportement indéterminé)
    - on émet plus d'octets que nécessaire.

    Le code correct est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    char s[32] = "";
     
    strcpy(s, "hello world\n");
    send(sock, s, strlen (s), 0);
    seul "hello world\n" est transmis.

    en réception, on se sert de la longueur reçue pour placer le 0 au bon endroit, de façon à reformer une chaine C locale correcte (si le code du receveur est du C.)

    Je pensais avoir expliqué tout ça dans l'article cité au-dessus...

  10. #10
    Membre averti
    Inscrit en
    Septembre 2008
    Messages
    48
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 48
    Par défaut
    desole si je ne comprend pas toujours du premier coup mais là j'ai compris.merci.
    bon allez je retourne lire les protocoles HTTP.

  11. #11
    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
    Ce que veut dire Emannuel, c'est qu'en général, les chaines de caractères sont transmises comme cela : <longueur><chaine> afin que le récepteur puisse connaitre la longueur de la chaine à recevoir, ce qui lui permet de préparer un buffer de réception assez grand et lorsque tout est reçu de positionner le 0 final afin de reconstrituer une chaine de caractères valide.

    Code envoyer une chaine : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    char *string = "Hello world";
    int len = htonl(strlen(string));
    send(socket, &len, sizeof(len), 0);
    send(socket, string, len, 0);

    Code recevoir une chaine : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    char *string = NULL;
    int len = 0;
    recv(socket, &len, sizeof(len), 0);
    len = ntohl(len);
    string = malloc(len + 1);
    recv(socket, string, len, 0);
    string[len] = 0;

    Attention, ces exemples ne gèrent pas les erreurs
    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. Aide Client/Serveur TCP //Commentaire
    Par sebounty dans le forum Réseau
    Réponses: 1
    Dernier message: 27/04/2007, 09h19
  2. [Reseau] probleme client/serveur TCP LInux
    Par jmjmjm dans le forum Réseau
    Réponses: 20
    Dernier message: 03/12/2006, 19h32
  3. [C#] Problème client-serveur TCP
    Par LE NEINDRE dans le forum Windows Forms
    Réponses: 7
    Dernier message: 02/06/2006, 16h23
  4. Réponses: 1
    Dernier message: 11/05/2006, 11h46
  5. client/serveur tcp/ip en c sous unix
    Par oclone dans le forum Développement
    Réponses: 8
    Dernier message: 19/04/2005, 18h55

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