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 avec decalage


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre extrêmement actif
    Avatar de lilington
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2005
    Messages
    681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 681
    Par défaut socket avec decalage
    Bonjours, j'ai un petit probleme que je n'arrive pas a gerer.
    j'ai un client qui envois une requette et qui recoit une reponse du serveur imediatement. seulement le server ne recoit la reponse que lorsque je ferme la socket du client. voici le code 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
    char rq[256];
       strcpy(rq,argv[3]);
       int sent=0;
       fprintf(stderr,"sending '%s'\n",rq);
       while(sent<strlen(rq))
       {
           res=send(sockfd,rq+sent,strlen(rq)-sent,0);
           if(res==-1)
           {
               close(sockfd);
               free(addr);
               return EXIT_FAILURE;
           }
           sent+=res;
       }
       fprintf(stderr,"receiving: ");
       char buffer[8192];
       memset(buffer,0,sizeof(buffer));
    /*   while((res=recv(sockfd,buffer,8192-1,0))>0)
       {
           buffer[res]=0;
           puts(buffer);
           memset(&buffer,0,sizeof(buffer));
       }*/
        close(sockfd);
        free(addr);
    en en levant les commentaires les deux programmes se plentent. mais avec les commentaire,
    le serveur recoit bien le message envoye par le client mais la reponse n'arrive malheuresement jamais car le client n'est plus la.

    cote 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
     
    static int run_server()
    {
        int conn_s,val=1;
        while(1)
        {
            if((conn_s=accept(glo_servSock,NULL,NULL))<0)
            {
                return -1;
            }
     
            char *cmd=readcmd(conn_s);
            val=fetchcmd(cmd,conn_s); // la reponse adequate est donne ici selon cmd
            free(cmd);
            close(conn_s);
            if(val==0)
                break;
        }
     
     
        return 0;
    }
     
     
     
    static char * readcmd(int Socket)
    {
        char buffer[MAXBUFFER];
        unsigned int size=0;
        int res;
        char *result=(char*)malloc(sizeof(char));
        if(result==NULL)
        {
            return NULL;
        }
        strcpy(result,"\0");
     
        while((res=recv(Socket,buffer,MAXBUFFER-1,MSG_WAITALL))>0)
        {
            buffer[res]='\0';
            size+=res;
            char *ptr=(char*)realloc(result,sizeof(char)*(size+1));
            if(ptr==NULL)
            {
                free(result);
                result=NULL;
                break;
            }
            result=ptr;
            strcat(result,buffer);
            memset(buffer,0,res);
        }
     
        return result;
    }
    J'ai vu un truc comme TCP_DELAY mais je me souviens qu'avant j'avais ecris un code qui marchait la je comprend vraiment pas pourquoi rien de marche.

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    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 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par lilington Voir le message
    Bonjours, j'ai un petit probleme que je n'arrive pas a gerer.
    j'ai un client qui envois une requette et qui recoit une reponse du serveur imediatement. seulement le server ne recoit la reponse que lorsque je ferme la socket du client. voici le code 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
    char rq[256];
       strcpy(rq,argv[3]);
       int sent=0;
       fprintf(stderr,"sending '%s'\n",rq);
       while(sent<strlen(rq))
       {
           res=send(sockfd,rq+sent,strlen(rq)-sent,0);
           if(res==-1)
           {
               close(sockfd);
               free(addr);
               return EXIT_FAILURE;
           }
           sent+=res;
       }
       fprintf(stderr,"receiving: ");
       char buffer[8192];
       memset(buffer,0,sizeof(buffer));
    /*   while((res=recv(sockfd,buffer,8192-1,0))>0)
       {
           buffer[res]=0;
           puts(buffer);
           memset(&buffer,0,sizeof(buffer));
       }*/
        close(sockfd);
        free(addr);
    en en levant les commentaires les deux programmes se plentent. mais avec les commentaire,
    le serveur recoit bien le message envoye par le client mais la reponse n'arrive malheuresement jamais car le client n'est plus la.

    cote 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
     
    static int run_server()
    {
        int conn_s,val=1;
        while(1)
        {
            if((conn_s=accept(glo_servSock,NULL,NULL))<0)
            {
                return -1;
            }
     
            char *cmd=readcmd(conn_s);
            val=fetchcmd(cmd,conn_s); // la reponse adequate est donne ici selon cmd
            free(cmd);
            close(conn_s);
            if(val==0)
                break;
        }
     
     
        return 0;
    }
     
     
     
    static char * readcmd(int Socket)
    {
        char buffer[MAXBUFFER];
        unsigned int size=0;
        int res;
        char *result=(char*)malloc(sizeof(char));
        if(result==NULL)
        {
            return NULL;
        }
        strcpy(result,"\0");
     
        while((res=recv(Socket,buffer,MAXBUFFER-1,MSG_WAITALL))>0)
        {
            buffer[res]='\0';
            size+=res;
            char *ptr=(char*)realloc(result,sizeof(char)*(size+1));
            if(ptr==NULL)
            {
                free(result);
                result=NULL;
                break;
            }
            result=ptr;
            strcat(result,buffer);
            memset(buffer,0,res);
        }
     
        return result;
    }
    J'ai vu un truc comme TCP_DELAY mais je me souviens qu'avant j'avais ecris un code qui marchait la je comprend vraiment pas pourquoi rien de marche.
    Salut

    Si j'ai bien lu ton code, ton client fait un send() puis un recv(). Mais d'après ce que je vois, le serveur fait bien un recv() mais aucun send(). Comment le client peut recevoir qqchose qui n'est pas envoyé ???

    Sinon concernant ta gestion du realloc tu n'as pas besoin de faire un malloc() initial. Car si le realloc reçoit en paramètre un pointeur NULL, il se comporte comme malloc(). Donc déjà tu peux gagner sur du code inutile. Surtout que je ne comprends pas à quoi sert le strcpy(result, "\0") vu que strcpy() met lui-même le '\0' qui va bien. De même que memset(buffer) est inutile vu que buffer est écrasé à chaque itération et terminé avec un '\0' à la bonne place => même sans memset(), strcat() ne plantera pas.

    Donc déjà corrige un peu ton code serveur pour supprimer des actions inutiles (et peut-êtres génératrices de bug, j'ai pas trop approfondi) et recommence ton test.

    PS: je ne connais pas trop le flag MSG_WAIT_ALL. Mais moi je ne l'ai jamais mis dans mes échanges client/serveur et son absence ne m'a jamais gêné...
    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]

  3. #3
    Membre extrêmement actif
    Avatar de lilington
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2005
    Messages
    681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 681
    Par défaut
    Merci pour ta reponse.
    sinon visiblement tu n'as pas bien lu le code car je dis bien que le serveur traite la requette et renvois une reponse dans la fonction fletchcmd(cmd,conn_s)
    comme tu le vois le message recu par readcmd en retourner dans la fonction fetchcmd avec le descripteur de la socket (au fait on dit un ou une socket?)
    le probleme n'est pas au niveau client mais au niveau serveur ou les deux.
    quand le client envois une requete ex: CMD_SS qui signifie stop server, voici ce que j'ai si je place un printf apres le send du client et apres le recv du serveur:
    sur le client le message s'affiche donc il a fini son envois, mais sur le serveur le recv ne fini jamais sauf si je fait CTRL+c sur le client donc quand je ferme le client le serveur m'affiche qu'il a bien recu CMD_SS et dans la fonction fetchcmd() il rentre dans le bon if mais le client etant fermer il n'envois rien.

    pour realloc je vais revoir en effet c'est a cause des erreurs de valgrind que je prend des tonnes de precausions inutiles parfois.

  4. #4
    Membre extrêmement actif
    Avatar de lilington
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2005
    Messages
    681
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 681
    Par défaut
    bon j'ai une idee d'ou vient l'erreur mais avant je t'explique pourquoi je ne vire pas le strcpy et le malloc du debut. c'est a cause strcat.
    si je fais un strcat avec un result qui n'a pas ete initialize il arrive parfois qu'il m'affiche des conneries avant. Et j'ai des truc genre @^ d9$CMD_GSpS alors qu'il devait juste m'afficher CMD_GSpS bref.

    bon j'ai modifier le 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
    static char * readcmd(int Socket)
    {
        char buffer[MAXBUFFER]={0};
        unsigned int size=0;
        int res;
        char *result=NULL;
       /* result=(char *)malloc(sizeof(char));
        if(result==NULL)
            return -1;
        strcpy(result,"\0");
     
        while((res=read(Socket,buffer,MAXBUFFER-1))>0)
        {
            buffer[res]='\0';
            size+=res;
            char *ptr=(char*)realloc(result,sizeof(char)*(size+1));
            if(ptr==NULL)
            {
                free(result);
                result=NULL;
                break;
            }
            result=ptr;
            strcat(result,buffer);
            puts(result);
        }*/
     
      recev(Socket,buffer,MAXBUFFER-1,0);
      result=malloc(sizeof(char)*(strlen(buffer)+1));
      strcpy(result,buffer);
        return result;
    }
    et ca marche. mais ca ne m'arrange pas car parfois la commande est suivit d'un tres long message par exemple
    CMD_NSp-=|=-voici le tres long message.....
    donc j'ai change le MAXBUFFER a 2 pour voir ce qui ce passe si je garde le while
    et voici le resultat si j'envois comme commande CMD_GSpS (notez que j'affiche a chaque fois result dans la boucle)
    ./cunoserv
    INFO: Server started
    C
    CM
    CMD
    CMD_
    CMD_G
    CMD_GS
    CMD_GSp
    CMD_GSpS
    visiblement le message est lut mais le serveur retourne une derniere fois lire la socket qui ne donnera rien puisque le client a deja fini d'ecrire donc sa bloque.

Discussions similaires

  1. [HTML] select liste avec decalages des entrees
    Par guy2004 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 12
    Dernier message: 19/05/2006, 15h10
  2. Problême de Socket avec un applet java (RMI/policy)
    Par Vesperal dans le forum API standards et tierces
    Réponses: 3
    Dernier message: 12/04/2006, 12h00
  3. [HTTP][Socket] avec une url c'est possible ?
    Par tck-lt dans le forum Entrée/Sortie
    Réponses: 13
    Dernier message: 19/08/2005, 09h39
  4. [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
  5. Erreur de socket avec le composant Indy idHTTP
    Par Etanne dans le forum C++Builder
    Réponses: 3
    Dernier message: 25/10/2004, 11h27

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