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 :

Fin de réception de fichier incorrecte


Sujet :

Réseau C

  1. #1
    Membre confirmé
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Mars 2014
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur sécurité

    Informations forums :
    Inscription : Mars 2014
    Messages : 158
    Points : 462
    Points
    462
    Par défaut Fin de réception de fichier incorrecte
    bonjour,

    j’essaie actuellement de développer un mini-serveur de fichier cependant lors de la réception des fichiers le contenue de ceux ci est quasiment correct :
    l'intégralité du fichier est présente mais 300 octet supplémentaire son aussi présent à la fin.
    comme il s'agit entièrement de fait maison (le protocole utilisé aussi) je vous mais à disposition l'intégralité du code, si jamais vous avez des idées pour optimisé le code o le sécurisé où même n'importe quelle suggestion je suis prenant
    sachant que le client et le serveur utilise SocketC+S.c et .h.
    de plus il faut compiler les main.c des deux sous linux je n'ai pas tester sous windows si cela se compile ou pas (en theorie oui)
    si vous avez besoin de quelqu'info qu'il sois demander moi
    je vous donne d'abord le code du serveur
    SERVER

    SocketC+S.c
    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
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    #include "SocketC+S.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define PORT 8888
    #define BUFFERSIZE 4096
    #define TRUE 1
    #define FALSE 0
     
    #ifdef WIN32
    #include <winsock2.h>
    #define DELIMITATEUR '\\'
    #elif defined (linux)
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <errno.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <netdb.h>
    #define INVALID_SOCKET -1
    #define SOCKET_ERROR -1
    #define closesocket(s) close(s)
    #define DELIMITATEUR '/'
    typedef int SOCKET;
    typedef struct sockaddr_in SOCKADDR_IN;
    typedef struct sockaddr SOCKADDR;
    typedef struct in_addr IN_ADDR;
    #else
    #error not defined for this platform
    #endif // WIN32
    static  void init(){
        #ifdef WIN32
        WSADATA wsa;
        int err =WSAStartup⁽MAKEWORD(2, 2),&wsa);
        if(err<0)
        {
            puts("WSAstartup failed !\n");
            exit(EXIT_FAILURE);
        }
        #endif // WIN32
    }
    /** \brief initialisation de l'interface winsock
     * \return void
     */
    static void end(SOCKET sock){
    closesocket(sock);
    #ifdef WIN32
        WSACleanup();
    #endif // WIN32
     
    }
    /** \brief fin de l'interface winsock
     *  fermeture du socket
     * \param socket a fermer (socket principal)
     * \return void
     */
     static void Dsend(char *buffer, SOCKET sock){
        int size=strlen(buffer);
        if(send(sock,&size,sizeof(int),0)<0)
        {
            perror("send()");
            exit(errno);
        }
        if(send(sock,buffer,strlen(buffer),0)<0)
        {
            perror("send()");
            exit(errno);
        }
    }
    /** \brief envois de la taille du buffer
     *  envois du buffer sur le socket
     * \param buffer a envoyer
     * \param socket sur lequel envoyer
     * \return void
     */
     
    static  int Drecv(char *buffer,SOCKET csock){
           int size=0;
            if(recv(csock, &size,sizeof(int),0)<0)
       {
           perror("recv()");
           exit(errno);
       }
     
     if(recv(csock, buffer,size*sizeof(char),0)<0)
       {
           perror("recv()");
           exit(errno);
       }
        buffer[size]='\0';
    return size;
    }
    /** \brief reception des infos envoyer par Dsend
     *
     * \param buffer a remplir
     * \param socket client sur lequel ecouter
     * \return taille du buffer
     */
     
     static int Csignal(int buffer,SOCKET sock){
    int res=0;
    if(send(sock,&buffer,sizeof(buffer),0)<0){
            perror("send()");
            exit(errno);
        }
    printf("signal %u sent\n",buffer);
    if(recv(sock, &res,sizeof(int),0)<0){
            perror("recv()");
            exit(errno);
        }
    if(res!=1){
            printf("reponse incorecte\n");
            return FALSE;
        }else{return TRUE;
    printf("signal %u recu\n",res);
    }
    }
    /** \brief envoie du signal de choix
     * \param signal a envoyer
     * \param socket sur lequel envoyer
     * \return 0 si reponse incorecte du serveur
     *  1 si reponse correcte du serveur
     */
     
    static int Rsignal(SOCKET sock){
    int buffer=0;
    int res=0;
    if(recv(sock, &res,sizeof(int),0)<0){
            perror("recv()");
            exit(errno);
        }
        switch(res){
        case 1:buffer=1;break;
        case 666:buffer=1;break;
        default:buffer=0;break;
        }
        printf("signal reçu: %u\n",buffer);
    if(send(sock,&buffer,sizeof(buffer),0)<0){
            perror("send()");
            exit(errno);
        }
    printf("Reponse au signal: %u\n",buffer);
     
    return res;
    }
    /** \brief reception du signal de Csignal
     * \param socket sur lequel recevoir
     * \return valeur du signal
     */
    static FILE *RFopen(char *nomFichier,char *dossier){
     
    char *location=strdup(dossier);
    	if( location == NULL ){
    		perror("Erreur allocation mémoire\n");
    		exit( EXIT_FAILURE );
    	}
    char *ptr_loc=NULL;
    FILE *fichier;
     
    ptr_loc=realloc(location,sizeof(char)*(strlen(location)+strlen(nomFichier)-1));
    if( ptr_loc == NULL ){
    		free( location );
    		location = NULL;
    		perror("Erreur reallocation\n");
    		exit( EXIT_FAILURE );
    	}
    location=ptr_loc;
     
    strcat(location,nomFichier);
        fichier=fopen(location,"wb");
        if (fichier==NULL) {
        perror("fopen()");
        exit(errno);
        }else{
        printf("Fichier ouvert: %s \nDans %s\n",nomFichier,dossier);}
        return fichier;
    }
    /** \brief ouverture d'un fichier en mode binaire
     * \param nom du fichier
     * \param dossier de stockage du fichier
     * \return file descriptor
     */
     
    static char *chNom(char *input){
        char* carac=input;
        int i;
        char* nom;
        for (i=0; i<128; i++)
        {
            if (!*carac) break;
            nom=carac;
            while(*carac && *carac!=DELIMITATEUR) carac++;
            if (*carac)
            {
                carac++;
            }
        }
        return nom;
    }
    /** \brief recuperation d'un nom de fichier dans un chemin
     * non destructif
     * \param chemin du fichier
     * \param none
     * \return nom du fichier
     */
     
      static void Lerase(){
        printf("\x0d");
        printf("\033[K");
    }
    /** \brief efface la ligne actuel de stdout
     * \param none
     * \param none
     * \return void
     */
     
      static char *readFile(char *path){
      FILE * fichier;
      long lSize;
      char * buffer;
      size_t result;
     
      fichier = fopen ( path , "rb" );
      if (fichier==NULL) {
        perror("fopen()");
        exit(errno);
        }
      // obtain file size:
      fseek (fichier , 0 , SEEK_END);
      lSize = ftell (fichier);
      rewind (fichier);
      // allocate memory to contain the whole file:
      buffer = (char*)malloc(sizeof(char)*lSize);
      if (buffer == NULL)  {
        perror("malloc()");
        exit(errno);
        }
      // copy the file into the buffer:
      result = fread (buffer,1,lSize,fichier);
      if (result != lSize)  {
        perror("fread()");
        exit(errno);
        }
      /* the whole file is now loaded in the memory buffer. */
      // terminate
      fclose (fichier);
      return buffer;
      free(buffer);
    }
    /** \brief enregistre un fichier binaire en ram
     * \param chemin du fichier
     * \param none
     * \return pointeur sur le fichier en ram
     */
     
    static long sizeOfFile(char *path){
      long lSize;
      FILE *fichier = fopen ( path , "rb" );
      if (fichier==NULL) {
        perror("fopen()");
        exit(errno);
        }
      fseek (fichier , 0 , SEEK_END);
      lSize = ftell (fichier);
      rewind (fichier);
      return lSize;
    }
    /** \brief recupere le nombre de byte du fichier
     * \param chemin du fichier
     * \param none
     * \return nombre de byte
     */
     
     static char *decoupeStream(char *buffer){
    char *output=(char*)malloc(sizeof(char)*BUFFERSIZE);
    int i;
    for(i=0;i<BUFFERSIZE;i++)
    {
        output[i]=*buffer;
        buffer++;
    }
    output[i]='\0';
    return output;
    }
    /** \brief decoupe un buffer en segment de BUFFERSIZE byte
     * destructif
     * \param buffer a decouper
     * \param
     * \return partie du buffer faisant BUFFERSIZE
     */
     
    static void sFile(char *path,SOCKET sock){
        char* nom=chNom(path);
        printf("le nom est '%s',le chemin est '%s'\n",nom,path);
        Csignal(1,sock);
        Dsend(nom,sock);
        envoieFile(path,sock);
    }
    /** \brief envoie d'un fichier avec prérequis:
     * Csignal; Dsend(nom); envoieFile
     * \param chemin du fichier
     * \param socket sur lequel envoyer
     * \return void
     */
     
    static void envoieFile(char *path ,SOCKET sock){
        long i=0,size=0;
        char *ligne=malloc(sizeof(char)*BUFFERSIZE);
        char *file=readFile(path);
        printf("sending file : %s\n",path);
        size=sizeOfFile(path);
        for(i=0;i<size;i=i+BUFFERSIZE)
        {
            ligne=decoupeStream(file);
            printf(".");
            Dsend(ligne,sock);
     
        }
        Dsend("EOF",sock);
        free(ligne);
        free(file);
    }
    /** \brief envoie du corp d'un fichier
     * \param chemin du fichier
     * \param socket sur lequel envoyer
     * \return void
     */
     
    static void frecv(SOCKET csock,char *dossier){
        int ctrl=1;
        char buffer[BUFFERSIZE];
        char nomFichier[BUFFERSIZE];
        Drecv(nomFichier,csock);
        FILE *fichier=RFopen(nomFichier,dossier);
        while(ctrl>0)
       {
        ctrl=Drecv(buffer,csock);
        if(ctrl==3){
        if(!strcmp(buffer,"EOF")){
                printf("\nEnd of file!!!\n");
                break;
        }else{
        fwrite( buffer , sizeof(buffer[0]) , sizeof(buffer)/sizeof(buffer[0]) , fichier);
        }
        }
        else{
        fwrite( buffer , sizeof(buffer[0]) , sizeof(buffer)/sizeof(buffer[0]) , fichier);
            }
       }
        fclose(fichier);
    }
    /** \brief reception d'un fichier
     * nom + corp
     * \param socket sur lequel ecouter
     * \param dossier ou stocker le fichier
     * \return void
     */
     
    static SOCKET Caccept(SOCKET sock){
        SOCKADDR_IN csin= {0};
        SOCKET csock;
        socklen_t sinsize=sizeof(csin);
        csock=accept(sock,(SOCKADDR *)&csin,&sinsize);
        if(csock==INVALID_SOCKET){
            perror("accept()");
            exit(errno);
        }
     return(csock);
    }
    /** \brief creation d'un socket client
     * \param socket initial
     * \param none
     * \return socket client
     */
    SocketC+S.h
    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
    #ifndef SOCKETCS_INCLUDED
    #define SOCKETCS_INCLUDED
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define PORT 8888
    #define BUFFERSIZE 4096
    #define TRUE 1
    #define FALSE 0
     
    #ifdef WIN32
    #include <winsock2.h>
    #define DELIMITATEUR '\\'
    #elif defined (linux)
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <errno.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <netdb.h>
    #define INVALID_SOCKET -1
    #define SOCKET_ERROR -1
    #define closesocket(s) close(s)
    #define DELIMITATEUR '/'
    typedef int SOCKET;
    typedef struct sockaddr_in SOCKADDR_IN;
    typedef struct sockaddr SOCKADDR;
    typedef struct in_addr IN_ADDR;
    #else
    #error not defined for this platform
    #endif // WIN32
    static int Rsignal(SOCKET sock);
    static int Csignal(int buffer,SOCKET sock);
    static int Drecv(char *buffer,SOCKET csock);
    static void Dsend(char *buffer, SOCKET soc);
    static void end(SOCKET sock);
    static void init();
    static FILE *RFopen(char *nomFichier,char *dossier);
    static char *chNom(char *input);
    static void Lerase();
    static char *readFile(char *path);
    static long sizeOfFile(char *path);
    static char *decoupeStream(char *buffer);
    static void envoieFile(char *path ,SOCKET sock);
    static void sFile(char *path,SOCKET sock);
    static void frecv(SOCKET csock,char *dossier);
    static SOCKET Caccept(SOCKET sock);
     
     
    #endif // SOCKETC+S
    server.c
    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
    #include "SocketC+S.c"
    #include "SocketC+S.h"
    #define MAXCLIENT 100
    #define MAXLOOPS 100
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define PORT 8888
    #define BUFFERSIZE 4096
    #define TRUE 1
    #define FALSE 0
     
    #ifdef WIN32
    #include <winsock2.h>
    #define DELIMITATEUR '\\'
    #elif defined (linux)
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <errno.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <netdb.h>
    #define INVALID_SOCKET -1
    #define SOCKET_ERROR -1
    #define closesocket(s) close(s)
    #define DELIMITATEUR '/'
    typedef int SOCKET;
    typedef struct sockaddr_in SOCKADDR_IN;
    typedef struct sockaddr SOCKADDR;
    typedef struct in_addr IN_ADDR;
    #else
    #error not defined for this platform
    #endif // WIN32
    static SOCKET Caccept(SOCKET sock);
    static void Sinit( SOCKET sock);
    static void frecv(SOCKET csock,char *location);
    static void gClient(SOCKET sock);
    static int server();
     
     
    static void Sinit( SOCKET sock){
    SOCKADDR_IN sin= {0};
    sin.sin_addr.s_addr = INADDR_ANY;
    sin.sin_port=htons(PORT);
    sin.sin_family = AF_INET;
    if(sock==INVALID_SOCKET){
        perror("socket()");
        exit(errno);
    }
    if(bind(sock,(SOCKADDR *)&sin,sizeof(sin))==SOCKET_ERROR){
        perror("bind()");
        exit(errno);
        }
    }
     
     
    static void gClient(SOCKET sock){
        int ex=0,choix=0;
        SOCKET csock=Caccept(sock);
        printf("Client accépter!\n");
        while(ex==0)
        {
            choix=Rsignal(csock);
            switch(choix){
            case 1:frecv(csock,"/home/tagashy/test2/");
            break;
            case 666:ex=1;
            break;
            default:printf("choix incorect !!! choix=%u\n",choix);
            break;
            }
        }
        closesocket(csock);
    }
     
    static int server(){
    SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
    init();
    Sinit(sock);
     
    if(listen(sock,MAXCLIENT)==SOCKET_ERROR){
        perror("listen()");
        exit(errno);
    }
    printf("Waiting for connection ...\n");
     
       gClient(sock);
        end(sock);
        return 0;
    }
    Main.c
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #include <stdio.h>
    #include <stdlib.h>
    #include "server.c"
    int main()
    {
    server();
        return 0;
    }

    CLIENT

    main.c
    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
     
    #include "client.c"
    #include "SocketC+S.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define PORT 8888
    #define BUFFERSIZE 4096
    #define TRUE 1
    #define FALSE 0
     
    #ifdef WIN32
    #include <winsock2.h>
    #define DELIMITATEUR '\\'
    #elif defined (linux)
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <errno.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <netdb.h>
    #define INVALID_SOCKET -1
    #define SOCKET_ERROR -1
    #define closesocket(s) close(s)
    #define DELIMITATEUR '/'
    typedef int SOCKET;
    typedef struct sockaddr_in SOCKADDR_IN;
    typedef struct sockaddr SOCKADDR;
    typedef struct in_addr IN_ADDR;
    #else
    #error not defined for this platform
    #endif // WIN32
     
    int main()
    {
        SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
        init();
        Cinit(sock,"192.168.1.27");
        sFile("/home/tagashy/test.txt",sock);
        sFile("/home/tagashy/ikigezu.dg",sock);
        Csignal(666,sock);
        end(sock);
        return 0;
    }
    client.c
    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
    #include "SocketC+S.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define PORT 8888
    #define BUFFERSIZE 4096
    #define TRUE 1
    #define FALSE 0
     
    #ifdef WIN32
    #include <winsock2.h>
    #define DELIMITATEUR '\\'
    #elif defined (linux)
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <errno.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <netdb.h>
    #define INVALID_SOCKET -1
    #define SOCKET_ERROR -1
    #define closesocket(s) close(s)
    #define DELIMITATEUR '/'
    typedef int SOCKET;
    typedef struct sockaddr_in SOCKADDR_IN;
    typedef struct sockaddr SOCKADDR;
    typedef struct in_addr IN_ADDR;
    #else
    #error not defined for this platform
    #endif // WIN32
    #include "SocketC+S.c"
    static void Cinit(SOCKET sock,char *addres){
        SOCKADDR_IN sin= {0};
        if(sock==INVALID_SOCKET){
        perror("socket()");
            exit(errno);
        }
        sin.sin_addr.s_addr=inet_addr(addres);
        sin.sin_port=htons(PORT);
        sin.sin_family = AF_INET;
        if(connect(sock,(SOCKADDR *) &sin,sizeof(SOCKADDR))== SOCKET_ERROR){
            perror("connect()");
            exit(errno);
        }
    }
    merci

  2. #2
    Membre éclairé
    Inscrit en
    Décembre 2010
    Messages
    290
    Détails du profil
    Informations forums :
    Inscription : Décembre 2010
    Messages : 290
    Points : 719
    Points
    719
    Par défaut
    Bon je n'ai pas tout regardé, mais j'ai quand même de nombreuses remarques.

    - Il y a ENORMEMENT de fuites de ressources (mémoire, handles etc):
    * sizeOfFile(char *path) par exemple, laisse fuiter un handle de fichiers (il n'y pas d'appel à fclose()). Et d'une manière générale, il y a de meilleures façons de connaitre la taille d'un fichier (fstat() par exemple).
    * readFile() contient un appel à free(buffer) APRES le return, ce qui n'a aucun effet (je suis surpris que le compilateur ne t'ait rien dit).
    * RFopen() n'appelle jamais free() sur "location".
    * decoupeStream() retourne un buffer qui n'est pratiquement jamais libéré (puisque le free() est appelé APRES la boucle).

    - sizeof(char) VAUT TOUJOURS 1, quoiqu'il arrive, par définition. La raison, c'est que sizeof retourne une taille exprimée en nombre de "chars", donc sizeof(char) vaut toujours un char. Tes mallocs (sizeof(char)*size) peuvent donc être simplifiés.

    - Je ne comprends pas pourquoi la fonction readFile() ne donne pas aussi la taille du fichier lu à l'appelant: ça éviterait d'avoir à appeler une autre fonction pour le faire.

    - Dsend() repose sur un strlen() pour connaitre la taille des données à envoyer. Cela signifie que si ton fichier contient un 0, la taille sera incorrecte. C'est peut-être la cause de ton problème. Je ne comprends pas pourquoi tu as fait ça comme ça d'ailleurs: pourquoi ne pas passer la taille du buffer à envoyer?

    - Ton code est assez mal indenté/formatté, j'ai personnellement du mal à le lire alors que je suis habitué à lire du code de plein de gens différents et je ne suis généralement pas difficile à ce sujet.

    Je vais m'arrêter là, parce que comme j'ai dit, je n'ai pas tout regardé.

  3. #3
    Membre confirmé
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Mars 2014
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur sécurité

    Informations forums :
    Inscription : Mars 2014
    Messages : 158
    Points : 462
    Points
    462
    Par défaut
    @phi1981 j'ai corrigé
    sizeOfFile(char *path) par exemple, laisse fuiter un handle de fichiers (il n'y pas d'appel à fclose()). Et d'une manière générale, il y a de meilleures façons de connaitre la taille d'un fichier (fstat() par exemple).
    * RFopen() n'appelle jamais free() sur "location".
    sizeof(char) VAUT TOUJOURS 1
    qu'entend tu par
    * decoupeStream() retourne un buffer qui n'est pratiquement jamais libéré (puisque le free() est appelé APRES la boucle).
    le buffer ne doit pas être libérer avant la fin de la réception du fichier non ?

    pour
    il y a de meilleures façons de connaitre la taille d'un fichier (fstat() par exemple).
    fstat() est spécifique à linux il me semble or il me semble que ftell est portable sous Windows (je compte avoir le client sous Windows et linux) enfin si tu connais une solution plus portable je suis preneur de plus ton l’idée

    voici SocketC+S.c avec les corrections, de plus j'ai essayer de mieux indenter mon code (quel éléments te dérange ?)

    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
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    #include "SocketC+S.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define PORT 8888
    #define BUFFERSIZE 4096
    #define TRUE 1
    #define FALSE 0
     
    #ifdef WIN32
    #include <winsock2.h>
    #define DELIMITATEUR '\\'
    #elif defined (linux)
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <errno.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <netdb.h>
    #define INVALID_SOCKET -1
    #define SOCKET_ERROR -1
    #define closesocket(s) close(s)
    #define DELIMITATEUR '/'
    typedef int SOCKET;
    typedef struct sockaddr_in SOCKADDR_IN;
    typedef struct sockaddr SOCKADDR;
    typedef struct in_addr IN_ADDR;
    #else
    #error not defined for this platform
    #endif // WIN32
    static  void init(){
        #ifdef WIN32
        WSADATA wsa;
        int err =WSAStartup⁽MAKEWORD(2, 2),&wsa);
        if(err<0){
            puts("WSAstartup failed !\n");
            exit(EXIT_FAILURE);
        }
        #endif // WIN32
    }
    /** \brief initialisation de l'interface winsock
     * \return void
     */
    static void end(SOCKET sock){
    closesocket(sock);
    #ifdef WIN32
        WSACleanup();
    #endif // WIN32
     
    }
    /** \brief fin de l'interface winsock
     *  fermeture du socket
     * \param socket a fermer (socket principal)
     * \return void
     */
     static void Dsend(char *buffer, SOCKET sock){
        int size=strlen(buffer);
        if(send(sock,&size,sizeof(int),0)<0){
            perror("send()");
            exit(errno);
        }
        if(send(sock,buffer,strlen(buffer),0)<0){
            perror("send()");
            exit(errno);
        }
    }
    /** \brief envois de la taille du buffer
     *  envois du buffer sur le socket
     * \param buffer a envoyer
     * \param socket sur lequel envoyer
     * \return void
     */
     
    static  int Drecv(char *buffer,SOCKET csock){
        int size=0;
        if(recv(csock, &size,sizeof(int),0)<0){
           perror("recv()");
           exit(errno);
        }
     
        if(recv(csock, buffer,size*sizeof(char),0)<0){
           perror("recv()");
           exit(errno);
        }
        buffer[size]='\0';
    return size;
    }
    /** \brief reception des infos envoyer par Dsend
     *
     * \param buffer a remplir
     * \param socket client sur lequel ecouter
     * \return taille du buffer
     */
     
     static int Csignal(int buffer,SOCKET sock){
        int res=0;
        if(send(sock,&buffer,sizeof(buffer),0)<0){
            perror("send()");
            exit(errno);
        }
        printf("signal %u sent\n",buffer);
        if(recv(sock, &res,sizeof(int),0)<0){
            perror("recv()");
            exit(errno);
        }
        if(res!=1){
            printf("reponse incorecte\n");
            return FALSE;
        }else{
            return TRUE;
            printf("signal %u recu\n",res);
        }
    }
    /** \brief envoie du signal de choix
     * \param signal a envoyer
     * \param socket sur lequel envoyer
     * \return 0 si reponse incorecte du serveur
     *  1 si reponse correcte du serveur
     */
     
    static int Rsignal(SOCKET sock){
        int buffer=0;
        int res=0;
        if(recv(sock, &res,sizeof(int),0)<0){
            perror("recv()");
            exit(errno);
        }
        switch(res){
        case 1:buffer=1;break;
        case 666:buffer=1;break;
        default:buffer=0;break;
        }
        printf("signal reçu: %u\n",buffer);
        if(send(sock,&buffer,sizeof(buffer),0)<0){
            perror("send()");
            exit(errno);
        }
        printf("Reponse au signal: %u\n",buffer);
     
        return res;
    }
    /** \brief reception du signal de Csignal
     * \param socket sur lequel recevoir
     * \return valeur du signal
     */
    static FILE *RFopen(char *nomFichier,char *dossier){
     
        char *location=strdup(dossier);
    	if( location == NULL ){
    		perror("Erreur allocation mémoire\n");
    		exit( EXIT_FAILURE );
    	}
        char *ptr_loc=NULL;
        FILE *fichier;
     
        ptr_loc=realloc(location,(strlen(location)+strlen(nomFichier)-1));
        if( ptr_loc == NULL ){
    		free( location );
    		location = NULL;
    		perror("Erreur reallocation\n");
    		exit( EXIT_FAILURE );
    	}
        location=ptr_loc;
     
        strcat(location,nomFichier);
        fichier=fopen(location,"wb");
        if (fichier==NULL) {
        perror("fopen()");
        exit(errno);
        }else{
            printf("Fichier ouvert: %s \nDans %s\n",nomFichier,dossier);
        }
        free(location);
        return fichier;
    }
    /** \brief ouverture d'un fichier en mode binaire
     * \param nom du fichier
     * \param dossier de stockage du fichier
     * \return file descriptor
     */
     
    static char *chNom(char *input){
        char* carac=input;
        int i;
        char* nom;
        for (i=0; i<128; i++)
        {
            if (!*carac) break;
            nom=carac;
            while(*carac && *carac!=DELIMITATEUR) carac++;
            if (*carac)
            {
                carac++;
            }
        }
        return nom;
    }
    /** \brief recuperation d'un nom de fichier dans un chemin
     * non destructif
     * \param chemin du fichier
     * \param none
     * \return nom du fichier
     */
     
      static void Lerase(){
        printf("\x0d");
        printf("\033[K");
    }
    /** \brief efface la ligne actuel de stdout
     * \param none
     * \param none
     * \return void
     */
     
    static char *readFile(char *path,long *lSize){
        FILE * fichier;
        char * buffer;
        size_t result;
     
        fichier = fopen ( path , "rb" );
        if (fichier==NULL) {
            perror("fopen()");
            exit(errno);
        }
        // obtain file size:
        fseek (fichier , 0 , SEEK_END);
        lSize = ftell (fichier);
        rewind (fichier);
        // allocate memory to contain the whole file:
        buffer = (char*)malloc(lSize);
        if (buffer == NULL)  {
            perror("malloc()");
            exit(errno);
            }
      // copy the file into the buffer:
        result = fread (buffer,1,lSize,fichier);
        if (result != lSize)  {
            perror("fread()");
            exit(errno);
        }
        /* the whole file is now loaded in the memory buffer. */
        // terminate
        fclose (fichier);
        return buffer;
    }
    /** \brief enregistre un fichier binaire en ram
     * \param chemin du fichier
     * \param none
     * \return pointeur sur le fichier en ram
     */
     
    static long sizeOfFile(char *path){
        long lSize;
        FILE *fichier = fopen ( path , "rb" );
        if (fichier==NULL) {
            perror("fopen()");
            exit(errno);
        }
        fseek (fichier , 0 , SEEK_END);
        lSize = ftell (fichier);
        rewind (fichier);
        fclose(fichier);
        return lSize;
    }
    /** \brief recupere le nombre de byte du fichier
     * \param chemin du fichier
     * \param none
     * \return nombre de byte
     */
     
     static char *decoupeStream(char *buffer){
        char *output=(char*)malloc(BUFFERSIZE);
        int i;
        for(i=0;i<BUFFERSIZE;i++)
        {
            output[i]=*buffer;
            buffer++;
        }
        output[i]='\0';
        return output;
    }
    /** \brief decoupe un buffer en segment de BUFFERSIZE byte
     * destructif
     * \param buffer a decouper
     * \param
     * \return partie du buffer faisant BUFFERSIZE
     */
     
    static void sFile(char *path,SOCKET sock){
        char* nom=chNom(path);
        printf("le nom est '%s',le chemin est '%s'\n",nom,path);
        Csignal(1,sock);
        Dsend(nom,sock);
        envoieFile(path,sock);
    }
    /** \brief envoie d'un fichier avec prérequis:
     * Csignal; Dsend(nom); envoieFile
     * \param chemin du fichier
     * \param socket sur lequel envoyer
     * \return void
     */
     
    static void envoieFile(char *path ,SOCKET sock){
        long i=0,size=0;
        char *ligne=malloc(BUFFERSIZE);
        char *file=readFile(path,size);
        printf("sending file : %s\n",path);
        for(i=0;i<size;i=i+BUFFERSIZE)
        {
            ligne=decoupeStream(file);
            printf(".");
            Dsend(ligne,sock);
     
        }
        Dsend("EOF",sock);
        free(ligne);
        free(file);
    }
    /** \brief envoie du corp d'un fichier
     * \param chemin du fichier
     * \param socket sur lequel envoyer
     * \return void
     */
     
    static void frecv(SOCKET csock,char *dossier){
        int ctrl=1;
        char buffer[BUFFERSIZE];
        char nomFichier[BUFFERSIZE];
        Drecv(nomFichier,csock);
        FILE *fichier=RFopen(nomFichier,dossier);
        while(ctrl>0)
       {
        ctrl=Drecv(buffer,csock);
        if(ctrl==3){
        if(!strcmp(buffer,"EOF")){
                printf("\nEnd of file!!!\n");
                break;
        }else{
            fwrite( buffer , sizeof(buffer[0]) , sizeof(buffer)/sizeof(buffer[0]) , fichier);
        }
        }
        else{
            fwrite( buffer , sizeof(buffer[0]) , sizeof(buffer)/sizeof(buffer[0]) , fichier);
        }
        }
        fclose(fichier);
    }
    /** \brief reception d'un fichier
     * nom + corp
     * \param socket sur lequel ecouter
     * \param dossier ou stocker le fichier
     * \return void
     */
     
    static SOCKET Caccept(SOCKET sock){
        SOCKADDR_IN csin= {0};
        SOCKET csock;
        socklen_t sinsize=sizeof(csin);
        csock=accept(sock,(SOCKADDR *)&csin,&sinsize);
        if(csock==INVALID_SOCKET){
            perror("accept()");
            exit(errno);
        }
     return(csock);
    }
    /** \brief creation d'un socket client
     * \param socket initial
     * \param none
     * \return socket client
     */

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Citation Envoyé par Tagashy Voir le message
    fstat() est spécifique à linux il me semble or il me semble que ftell est portable sous Windows (je compte avoir le client sous Windows et linux) enfin si tu connais une solution plus portable je suis preneur de plus ton l’idée
    Windows possède des équivalents à stat() et fstat(), appelés _stat() et _fstat().
    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.

  5. #5
    Membre éclairé
    Inscrit en
    Décembre 2010
    Messages
    290
    Détails du profil
    Informations forums :
    Inscription : Décembre 2010
    Messages : 290
    Points : 719
    Points
    719
    Par défaut
    Citation Envoyé par Tagashy Voir le message
    le buffer ne doit pas être libérer avant la fin de la réception du fichier non ?
    Ceci est une partie du code de envoieFile() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
        char *ligne=malloc(BUFFERSIZE);
        for(i=0;i<size;i=i+BUFFERSIZE)
        {
            ligne=decoupeStream(file);
            Dsend(ligne,sock);
        }
        Dsend("EOF",sock);
        free(ligne);
    Si tu suis ce qui se passe:
    1) tu alloues un buffer et stocke son adresse dans ligne.
    2) tu réaffectes ligne avec l'adresse d'un buffer alloué par decoupeStream(), et ceci dans une boucle (donc à chaque fois, tu perds le buffer précédent).
    3) à la toute fin, tu libères le buffer pointé par ligne, mais il s'agit juste du dernier en date. Les buffers intermédiaires alloués par decoupeStream() et celui alloué par malloc() en début de fonction sont perdus.


    Citation Envoyé par Tagashy Voir le message
    fstat() est spécifique à linux il me semble or il me semble que ftell est portable sous Windows (je compte avoir le client sous Windows et linux) enfin si tu connais une solution plus portable je suis preneur de plus ton l’idée
    Comme l'a dit Medinoc, Windows a quelques fonctions similaires.

    Citation Envoyé par Tagashy Voir le message
    voici SocketC+S.c avec les corrections, de plus j'ai essayer de mieux indenter mon code (quel éléments te dérange ?)
    Là c'est plus personnel, j'étais pas forcément très honnête hier. D'une manière générale, j'ai l'impression qu'il manque des sauts de ligne là où je m'attendrais à en voir, et certains fonctions (frecv() par exemple) ont des blocs imbriqués mais indentés au même niveau. Le switch dans la fonction Rsignal() me fait aussi un drôle d'effet. Mais comme j'ai dit, c'est une remarque qui est très subjective.

    P.-S. merci à Winjerome d'avoir ajouté mes balises code dans mon précédent message.

  6. #6
    Membre éclairé
    Inscrit en
    Décembre 2010
    Messages
    290
    Détails du profil
    Informations forums :
    Inscription : Décembre 2010
    Messages : 290
    Points : 719
    Points
    719
    Par défaut
    Et en passant, ton nouveau code, tu l'as compilé avec succès ?
    Parce que je vois ça dans readFile() :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
        lSize = ftell (fichier);
        rewind (fichier);
        // allocate memory to contain the whole file:
        buffer = (char*)malloc(lSize);
        if (buffer == NULL)  {
            perror("malloc()");
            exit(errno);
            }
    où lSize est un pointeur sur long et non pas une variable de type long. Du coup je suis étonné que ce code compile.

  7. #7
    Membre confirmé
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Mars 2014
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur sécurité

    Informations forums :
    Inscription : Mars 2014
    Messages : 158
    Points : 462
    Points
    462
    Par défaut
    @phi1981
    Si tu suis ce qui se passe:
    1) tu alloues un buffer et stocke son adresse dans ligne.
    2) tu réaffectes ligne avec l'adresse d'un buffer alloué par decoupeStream(), et ceci dans une boucle (donc à chaque fois, tu perds le buffer précédent).
    3) à la toute fin, tu libères le buffer pointé par ligne, mais il s'agit juste du dernier en date. Les buffers intermédiaires alloués par decoupeStream() et celui alloué par malloc() en début de fonction sont perdus.
    effectivement la fonction marchait mais sans faire ce que je voulais en fait ^^ je voulais remplir le tableaux ligne par les données de decoupeStream() pas changer le pointeur de ligne.

    Du coup j'ai régler ce problème j'ai aussi supprimer sizeOfFile devenue inutile (pourquoi j'avais fait deux fonction ???) après modification de readFile() pour permettre de récupérer la taille.

    voila le code mis à jours
    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
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    #include "SocketC+S.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define PORT 8888
    #define BUFFERSIZE 4096
    #define TRUE 1
    #define FALSE 0
     
    #ifdef WIN32
    #include <winsock2.h>
    #define DELIMITATEUR '\\'
    #elif defined (linux)
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <errno.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <netdb.h>
    #define INVALID_SOCKET -1
    #define SOCKET_ERROR -1
    #define closesocket(s) close(s)
    #define DELIMITATEUR '/'
    typedef int SOCKET;
    typedef struct sockaddr_in SOCKADDR_IN;
    typedef struct sockaddr SOCKADDR;
    typedef struct in_addr IN_ADDR;
    #else
    #error not defined for this platform
    #endif // WIN32
    static  void init(){
        #ifdef WIN32
        WSADATA wsa;
        int err =WSAStartup⁽MAKEWORD(2, 2),&wsa);
        if(err<0){
            puts("WSAstartup failed !\n");
            exit(EXIT_FAILURE);
        }
        #endif // WIN32
    }
    /** \brief initialisation de l'interface winsock
     * \return void
     */
    static void end(SOCKET sock){
    closesocket(sock);
    #ifdef WIN32
        WSACleanup();
    #endif // WIN32
     
    }
    /** \brief fin de l'interface winsock
     *  fermeture du socket
     * \param socket a fermer (socket principal)
     * \return void
     */
     static void Dsend(char *buffer, SOCKET sock){
        int size=strlen(buffer);
        if(send(sock,&size,sizeof(int),0)<0){
            perror("send()");
            exit(errno);
        }
        if(send(sock,buffer,strlen(buffer),0)<0){
            perror("send()");
            exit(errno);
        }
    }
    /** \brief envois de la taille du buffer
     *  envois du buffer sur le socket
     * \param buffer a envoyer
     * \param socket sur lequel envoyer
     * \return void
     */
     
    static  int Drecv(char *buffer,SOCKET csock){
        int size=0;
        if(recv(csock, &size,sizeof(int),0)<0){
           perror("recv()");
           exit(errno);
        }
        printf("size of buffer received: %u",size);
        if(recv(csock, buffer,size*sizeof(char),0)<0){
           perror("recv()");
           exit(errno);
        }
        buffer[size]='\0';
    return size;
    }
    /** \brief reception des infos envoyer par Dsend
     *
     * \param buffer a remplir
     * \param socket client sur lequel ecouter
     * \return taille du buffer
     */
     
     static int Csignal(int buffer,SOCKET sock){
        int res=0;
        if(send(sock,&buffer,sizeof(buffer),0)<0){
            perror("send()");
            exit(errno);
        }
        printf("signal %u sent\n",buffer);
        if(recv(sock, &res,sizeof(int),0)<0){
            perror("recv()");
            exit(errno);
        }
        if(res!=1){
            printf("reponse incorecte\n");
            return FALSE;
        }else{
            return TRUE;
            printf("signal %u recu\n",res);
        }
    }
    /** \brief envoie du signal de choix
     * \param signal a envoyer
     * \param socket sur lequel envoyer
     * \return 0 si reponse incorecte du serveur
     *  1 si reponse correcte du serveur
     */
     
    static int Rsignal(SOCKET sock){
        int buffer=0;
        int res=0;
        if(recv(sock, &res,sizeof(int),0)<0){
            perror("recv()");
            exit(errno);
        }
        switch(res){
        case 1:buffer=1;break;
        case 666:buffer=1;break;
        default:buffer=0;break;
        }
        printf("signal reçu: %u\n",buffer);
        if(send(sock,&buffer,sizeof(buffer),0)<0){
            perror("send()");
            exit(errno);
        }
        printf("Reponse au signal: %u\n",buffer);
     
        return res;
    }
    /** \brief reception du signal de Csignal
     * \param socket sur lequel recevoir
     * \return valeur du signal
     */
    static FILE *RFopen(char *nomFichier,char *dossier){
     
        char *location=strdup(dossier);
    	if( location == NULL ){
    		perror("Erreur allocation mémoire\n");
    		exit( EXIT_FAILURE );
    	}
        char *ptr_loc=NULL;
        FILE *fichier;
     
        ptr_loc=realloc(location,(strlen(location)+strlen(nomFichier)+1));
        if( ptr_loc == NULL ){
    		free( location );
    		location = NULL;
    		perror("Erreur reallocation\n");
    		exit( EXIT_FAILURE );
    	}
        location=ptr_loc;
     
        strcat(location,nomFichier);
        fichier=fopen(location,"wb");
        if (fichier==NULL) {
        perror("fopen()");
        exit(errno);
        }else{
            printf("Fichier ouvert: %s \nDans %s\n",nomFichier,dossier);
        }
        free(location);
        return fichier;
    }
    /** \brief ouverture d'un fichier en mode binaire
     * \param nom du fichier
     * \param dossier de stockage du fichier
     * \return file descriptor
     */
     
    static char *chNom(char *input){
        char* carac=input;
        int i;
        char* nom;
        for (i=0; i<128; i++)
        {
            if (!*carac) break;
            nom=carac;
            while(*carac && *carac!=DELIMITATEUR) carac++;
            if (*carac)
            {
                carac++;
            }
        }
        return nom;
    }
    /** \brief recuperation d'un nom de fichier dans un chemin
     * non destructif
     * \param chemin du fichier
     * \param none
     * \return nom du fichier
     */
     
      static void Lerase(){
        printf("\x0d");
        printf("\033[K");
    }
    /** \brief efface la ligne actuel de stdout
     * \param none
     * \param none
     * \return void
     */
     
    static char *readFile(char *path,long *lSize){
        FILE * fichier;
        char * buffer;
        size_t result;
     
        fichier = fopen ( path , "rb" );
        if (fichier==NULL) {
            perror("fopen()");
            exit(errno);
        }
        // obtain file size:
        fseek (fichier , 0 , SEEK_END);
        *lSize = ftell (fichier);
        rewind (fichier);
        // allocate memory to contain the whole file:
        buffer = (char*)malloc(*lSize);
        if (buffer == NULL)  {
            perror("malloc()");
            exit(errno);
            }
      // copy the file into the buffer:
        result = fread (buffer,1,*lSize,fichier);
        if (result != *lSize)  {
            perror("fread()");
            exit(errno);
        }
        /* the whole file is now loaded in the memory buffer. */
        // terminate
        fclose (fichier);
        return buffer;
    }
    /** \brief enregistre un fichier binaire en ram
     * \param chemin du fichier
     * \param none
     * \return pointeur sur le fichier en ram
     */
     
    static long sizeOfFile(char *path){
        long lSize;
        FILE *fichier = fopen ( path , "rb" );
        if (fichier==NULL) {
            perror("fopen()");
            exit(errno);
        }
        fseek (fichier , 0 , SEEK_END);
        lSize = ftell (fichier);
        rewind (fichier);
        fclose(fichier);
        return lSize;
    }
    /** \brief recupere le nombre de byte du fichier
     * \param chemin du fichier
     * \param none
     * \return nombre de byte
     */
     
     static char *decoupeStream(char *buffer,char *output){
        int i;
        for(i=0;i<BUFFERSIZE;i++)
        {
            if (!*buffer) break;
            output[i]=*buffer;
            buffer++;
        }
        output[i]='\0';
        return output;
    }
    /** \brief decoupe un buffer en segment de BUFFERSIZE byte
     * destructif
     * \param buffer a decouper
     * \param
     * \return partie du buffer faisant BUFFERSIZE
     */
     
    static void sFile(char *path,SOCKET sock){
        char* nom=chNom(path);
        printf("le nom est '%s',le chemin est '%s'\n",nom,path);
        Csignal(1,sock);
        Dsend(nom,sock);
        envoieFile(path,sock);
    }
    /** \brief envoie d'un fichier avec prérequis:
     * Csignal; Dsend(nom); envoieFile
     * \param chemin du fichier
     * \param socket sur lequel envoyer
     * \return void
     */
     
    static void envoieFile(char *path ,SOCKET sock){
        long i=0,size=0;
        char *ligne=malloc(BUFFERSIZE);
        char *file=readFile(path,&size);
        char *ptr_file=file;
        printf("sending file : %s\n",path);
        for(i=0;i<size;i=i+BUFFERSIZE)
        {
            decoupeStream(file,ligne);
            printf(".");
            Dsend(ligne,sock);
     
        }
        printf("\r\n");
        Dsend("EOF",sock);
        free(ligne);
        free(ptr_file);
    }
    /** \brief envoie du corp d'un fichier
     * \param chemin du fichier
     * \param socket sur lequel envoyer
     * \return void
     */
     
    static void frecv(SOCKET csock,char *dossier){
        int ctrl=1;
        char buffer[BUFFERSIZE];
        char nomFichier[BUFFERSIZE];
        Drecv(nomFichier,csock);
        FILE *fichier=RFopen(nomFichier,dossier);
        while(ctrl>0)
       {
        ctrl=Drecv(buffer,csock);
        if(ctrl==3){
        if(!strcmp(buffer,"EOF")){
                printf("\nEnd of file!!!\n");
                break;
        }else{
            fwrite( buffer , sizeof(buffer[0]) , sizeof(buffer)/sizeof(buffer[0]) , fichier);
        }
        }
        else{
            fwrite( buffer , sizeof(buffer[0]) , sizeof(buffer)/sizeof(buffer[0]) , fichier);
        }
        }
        fclose(fichier);
    }
    /** \brief reception d'un fichier
     * nom + corp
     * \param socket sur lequel ecouter
     * \param dossier ou stocker le fichier
     * \return void
     */
     
    static SOCKET Caccept(SOCKET sock){
        SOCKADDR_IN csin= {0};
        SOCKET csock;
        socklen_t sinsize=sizeof(csin);
        csock=accept(sock,(SOCKADDR *)&csin,&sinsize);
        if(csock==INVALID_SOCKET){
            perror("accept()");
            exit(errno);
        }
     return(csock);
    }
    /** \brief creation d'un socket client
     * \param socket initial
     * \param none
     * \return socket client
     */
    de plus je pense avoir trouver d'autre fuite mémoire : le pointeur fichier dans envoieFile est incrémente par DecoupeStream du coup je pense que le free est incorrect en sortie de fonction. j'y ais apporté une correction.
    DecoupeStream remplissais son buffer même si celui ci est vide (je me demande si ça ne risque pas de finir en buffer overflow ? j'y ais rajouté une correction)
    je pense que mon problème original vient d'une chose du genre ( il me semble que les caractères non voulue sont moins nombreux en ayant apporté la correction)

    @médinoc
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Windows possède des équivalents à stat() et fstat(), appelés _stat() et _fstat().
    du coup pour comprendre tu me conseillerais de faire un faire quelquechose du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #ifdef WIN32
    #define FSTAT(s) _fstat(s)
    #elif defined (linux)
    #define FSTAT(s) fstat(s)
    #endif

  8. #8
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    du coup pour comprendre tu me conseillerais de faire un faire quelquechose du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #ifdef WIN32
    #define FSTAT(s) _fstat(s)
    #elif defined (linux)
    #define FSTAT(s) fstat(s)
    #endif
    Par exemple.

    Mais si les structures impliquées ne sont pas assez compatibles, tu peux aussi faire ça:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    static long sizeOfFile(char const *path){
    	#ifdef WIN32
    	/*Code pour Windows*/
    	#elif defined (linux)
    	/*Code pour Linux*/
    	#endif
    }
    Ça dépendra de ce que contiennent exactement les structures utilisées par stat/_stat...
    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.

  9. #9
    Membre confirmé
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Mars 2014
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur sécurité

    Informations forums :
    Inscription : Mars 2014
    Messages : 158
    Points : 462
    Points
    462
    Par défaut
    @Médinoc d'ac je vais me tourner vers ça des que j'aurais régler mes bug.

    d'ailleurs j'ai fais des correctifs sur mes fonctions mais je me retrouve avec un bug qui pars en segmentation error j'ai le pointeur du fichier qui est modifier entre les deux printf cependant je ne vois pas où ...

    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
     
    static void frecv(SOCKET csock,char *dossier){
        int ctrl=1;
        char buffer[BUFFERSIZE];
        char nomFichier[BUFFERSIZE];
        Drecv(nomFichier,csock);
        FILE *fichier=RFopen(nomFichier,dossier);
        printf("Fichier=%p\n",fichier);
        while(ctrl>0)
       {
        ctrl=Drecv(buffer,csock);
        if(ctrl==3){
        if(!strcmp(buffer,"EOF")){
            printf("\nEnd of file!!!\n");
            break;
        }else{
            fwrite( buffer , 1 , sizeof(buffer), fichier);
        }
        }
        else{
            printf("data : \nsizeof(buffer[0])=%lu , sizeof(buffer)/sizeof(buffer[0])=%lu , fichier=%p\n",sizeof(buffer[0]) , sizeof(buffer)/sizeof(buffer[0]) , fichier);
            fwrite( buffer , sizeof(buffer[0]) , sizeof(buffer)/sizeof(buffer[0]) , fichier);
        }
        memset(buffer,'\0',BUFFERSIZE);
        }
        fclose(fichier);
    }
    d’après le debuger cela vient aux niveau du deuxième fwrite

  10. #10
    Membre confirmé
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Mars 2014
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur sécurité

    Informations forums :
    Inscription : Mars 2014
    Messages : 158
    Points : 462
    Points
    462
    Par défaut
    Désolée du double post

    après de nombreuse recherche et optimisation je suis arrivée à un code correct
    mon erreur de fin de fichier si situais dans la fonction fwrite() en effet j'utilisais sizeof(buffer) pour écrire mes données mais buffer une fois remplie à 4096 caractère si j'en reçoit 800 ls 801 seras \0 mais le 802 seras quand même l'ancien 802 donc le 4096 le même donc sizeof retourne toujours 4096
    je suis passé à strlen qui s’arrête aux premier \0 mais je me demande si cela ne risque pas de poser des problèmes pour les fichiers binaires (il peuvent contenir \0 sans que ce sois la fin non ?)
    EDIT ça ne marche pas du tout pour les ficher binaire
    je pense peut être me tourné vers une libération, allocation de mémoire pour chaque buffer reçu qu'en penser vous ?

    p.s voila la dernière version (compilable et fonctionnelle)
    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
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    #include "SocketC+S.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define PORT 8888
    #define BUFFERSIZE 4096
    #define TRUE 1
    #define FALSE 0
     
    #ifdef WIN32
    #include <winsock2.h>
    #define DELIMITATEUR '\\'
    #elif defined (linux)
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <errno.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <netdb.h>
    #define INVALID_SOCKET -1
    #define SOCKET_ERROR -1
    #define closesocket(s) close(s)
    #define DELIMITATEUR '/'
    typedef int SOCKET;
    typedef struct sockaddr_in SOCKADDR_IN;
    typedef struct sockaddr SOCKADDR;
    typedef struct in_addr IN_ADDR;
    #else
    #error not defined for this platform
    #endif // WIN32
    static  void init(){
        #ifdef WIN32
        WSADATA wsa;
        int err =WSAStartup⁽MAKEWORD(2, 2),&wsa);
        if(err<0){
            puts("WSAstartup failed !\n");
            exit(EXIT_FAILURE);
        }
        #endif // WIN32
    }
    /** \brief initialisation de l'interface winsock
     * \return void
     */
    static void end(SOCKET sock){
    closesocket(sock);
    #ifdef WIN32
        WSACleanup();
    #endif // WIN32
     
    }
    /** \brief fin de l'interface winsock
     *  fermeture du socket
     * \param socket a fermer (socket principal)
     * \return void
     */
     static void Dsend(char *buffer, SOCKET sock,int size){
        if(send(sock,&size,sizeof(int),0)<0){
            perror("send()");
            exit(errno);
        }
        if(send(sock,buffer,strlen(buffer),0)<0){
            perror("send()");
            exit(errno);
        }
    }
    /** \brief envois de la taille du buffer
     *  envois du buffer sur le socket
     * \param buffer a envoyer
     * \param socket sur lequel envoyer
     * \return void
     */
     
    static  int Drecv(char *buffer,SOCKET csock){
        int size=0;
        if(recv(csock, &size,sizeof(int),0)<0){
           perror("recv()");
           exit(errno);
        }
        if(recv(csock, buffer,size,0)<0){
           perror("recv()");
           exit(errno);
        }
        buffer[strlen(buffer)]='\0';
    return size;
    }
    /** \brief reception des infos envoyer par Dsend
     *
     * \param buffer a remplir
     * \param socket client sur lequel ecouter
     * \return taille du buffer
     */
     
     static int Csignal(int buffer,SOCKET sock){
        int res=0;
        if(send(sock,&buffer,sizeof(buffer),0)<0){
            perror("send()");
            exit(errno);
        }
        printf("signal %u sent\n",buffer);
        if(recv(sock, &res,sizeof(int),0)<0){
            perror("recv()");
            exit(errno);
        }
        if(res!=1){
            printf("reponse incorecte\n");
            return FALSE;
        }else{
            return TRUE;
            printf("signal %u recu\n",res);
        }
    }
    /** \brief envoie du signal de choix
     * \param signal a envoyer
     * \param socket sur lequel envoyer
     * \return 0 si reponse incorecte du serveur
     *  1 si reponse correcte du serveur
     */
     
    static int Rsignal(SOCKET sock){
        int buffer=0;
        int res=0;
        if(recv(sock, &res,sizeof(int),0)<0){
            perror("recv()");
            exit(errno);
        }
        switch(res){
        case 1:buffer=1;break;
        case 666:buffer=1;break;
        default:buffer=0;break;
        }
        printf("signal reçu: %u\n",buffer);
        if(send(sock,&buffer,sizeof(buffer),0)<0){
            perror("send()");
            exit(errno);
        }
        printf("Reponse au signal: %u\n",buffer);
     
        return res;
    }
    /** \brief reception du signal de Csignal
     * \param socket sur lequel recevoir
     * \return valeur du signal
     */
    static FILE *RFopen(char *nomFichier,char *dossier){
     
        char *location=strdup(dossier);
    	if( location == NULL ){
    		perror("Erreur allocation mémoire\n");
    		exit( EXIT_FAILURE );
    	}
        char *ptr_loc=NULL;
        FILE *fichier;
     
        ptr_loc=realloc(location,(strlen(location)+strlen(nomFichier)+1));
        if( ptr_loc == NULL ){
    		free( location );
    		location = NULL;
    		perror("Erreur reallocation\n");
    		exit( EXIT_FAILURE );
    	}
        location=ptr_loc;
     
        strcat(location,nomFichier);
        fichier=fopen(location,"wb");
        if (fichier==NULL) {
        perror("fopen()");
        exit(errno);
        }else{
            printf("Fichier ouvert: %s \nDans %s\n",nomFichier,dossier);
        }
        free(location);
        return fichier;
    }
    /** \brief ouverture d'un fichier en mode binaire
     * \param nom du fichier
     * \param dossier de stockage du fichier
     * \return file descriptor
     */
     
    static char *chNom(char *input){
        char* carac=input;
        int i;
        char* nom;
        for (i=0; i<128; i++)
        {
            if (!*carac) break;
            nom=carac;
            while(*carac && *carac!=DELIMITATEUR) carac++;
            if (*carac)
            {
                carac++;
            }
        }
        return nom;
    }
    /** \brief recuperation d'un nom de fichier dans un chemin
     * non destructif
     * \param chemin du fichier
     * \param none
     * \return nom du fichier
     */
     
      static void Lerase(){
        printf("\x0d");
        printf("\033[K");
    }
    /** \brief efface la ligne actuel de stdout
     * \param none
     * \param none
     * \return void
     */
     
    static char *readFile(char *path,long *lSize){
        FILE * fichier;
        char * buffer;
        size_t result;
     
        fichier = fopen ( path , "rb" );
        if (fichier==NULL) {
            perror("fopen()");
            exit(errno);
        }
        // obtain file size:
        fseek (fichier , 0 , SEEK_END);
        *lSize = ftell (fichier);
        rewind (fichier);
        // allocate memory to contain the whole file:
        buffer = (char*)malloc(*lSize);
        if (buffer == NULL)  {
            perror("malloc()");
            exit(errno);
            }
      // copy the file into the buffer:
        result = fread (buffer,1,*lSize,fichier);
        if (result != *lSize)  {
            perror("fread()");
            exit(errno);
        }
        /* the whole file is now loaded in the memory buffer. */
        // terminate
        fclose (fichier);
        return buffer;
    }
    /** \brief enregistre un fichier binaire en ram
     * \param chemin du fichier
     * \param none
     * \return pointeur sur le fichier en ram
     */
     
    static long sizeOfFile(char *path){
        long lSize;
        FILE *fichier = fopen ( path , "rb" );
        if (fichier==NULL) {
            perror("fopen()");
            exit(errno);
        }
        fseek (fichier , 0 , SEEK_END);
        lSize = ftell (fichier);
        rewind (fichier);
        fclose(fichier);
        return lSize;
    }
    /** \brief recupere le nombre de byte du fichier
     * \param chemin du fichier
     * \param none
     * \return nombre de byte
     */
     
     static int decoupeStream(char *buffer,char *output){
        int i=0;
        for(i=0;i<BUFFERSIZE;i++)
        {
            if (!*buffer) break;
            output[i]=*buffer;
            buffer++;
        }
        output[i]='\0';
        return i;
    }
    /** \brief decoupe un buffer en segment de BUFFERSIZE byte
     * destructif
     * \param buffer a decouper
     * \param
     * \return partie du buffer faisant BUFFERSIZE
     */
     
    static void sFile(char *path,SOCKET sock){
        char* nom=chNom(path);
        printf("le nom est '%s',le chemin est '%s'\n",nom,path);
        Csignal(1,sock);
        Dsend(nom,sock,strlen(nom));
        envoieFile(path,sock);
    }
    /** \brief envoie d'un fichier avec prérequis:
     * Csignal; Dsend(nom); envoieFile
     * \param chemin du fichier
     * \param socket sur lequel envoyer
     * \return void
     */
     
    static void envoieFile(char *path ,SOCKET sock){
        long i=0,size=0;
        int sSize=0;
        char *ligne=malloc(BUFFERSIZE);
        char *file=readFile(path,&size);
        printf("sending file : %s\n",path);
        for(i=0;i<size;i=i+BUFFERSIZE)
        {
            sSize=decoupeStream(file+i,ligne);
            printf(".");
            Dsend(ligne,sock,sSize);
            memset(ligne,'\0',BUFFERSIZE);
        }
        printf("\r\n");
        Dsend("EOF",sock,3);
        free(ligne);
        free(file);
    }
    /** \brief envoie du corp d'un fichier
     * \param chemin du fichier
     * \param socket sur lequel envoyer
     * \return void
     */
     
    static void frecv(SOCKET csock,char *dossier){
        int ctrl=1;
        char buffer[BUFFERSIZE];
        char nomFichier[BUFFERSIZE];
        Drecv(nomFichier,csock);
        FILE *fichier=RFopen(nomFichier,dossier);
        while(ctrl>0)
       {
        ctrl=Drecv(buffer,csock);
        if(ctrl==3){
        if(!strcmp(buffer,"EOF")){
            printf("\nEnd of file!!!\n");
            break;
        }else{
            fwrite( buffer , 1 , strlen(buffer), fichier);
        }
        }
        else{
            fwrite( buffer , 1 , strlen(buffer), fichier);
        }
        memset(buffer,'\0',BUFFERSIZE);
        }
        memset(nomFichier,'\0',BUFFERSIZE);
        fclose(fichier);
    }
    /** \brief reception d'un fichier
     * nom + corp
     * \param socket sur lequel ecouter
     * \param dossier ou stocker le fichier
     * \return void
     */
     
    static SOCKET Caccept(SOCKET sock){
        SOCKADDR_IN csin= {0};
        SOCKET csock;
        socklen_t sinsize=sizeof(csin);
        csock=accept(sock,(SOCKADDR *)&csin,&sinsize);
        if(csock==INVALID_SOCKET){
            perror("accept()");
            exit(errno);
        }
     return(csock);
    }
    /** \brief creation d'un socket client
     * \param socket initial
     * \param none
     * \return socket client
     */

  11. #11
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Ce qu'il faut, c'est transmettre la vraie taille, vu que tu as les fonctions pour l'extraire.

    Un bon programme de transfert de fichier commence par transmettre le nom et la taille du fichier, puis transmet le fichier lui-même.
    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.

  12. #12
    Membre confirmé
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Mars 2014
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur sécurité

    Informations forums :
    Inscription : Mars 2014
    Messages : 158
    Points : 462
    Points
    462
    Par défaut
    je viens de suivre ton idée et cela m'as permis de me rendre compte d'un bug :
    pour les fichiers binaires quand ma fonction de découpe lis le bloc elle s’arrête et bug en pensant qu'elle est à la fin du fichier
    en fait ce qu'il se passe c'est que mon for qui envois les fichiers boucle jusqu’as un envoie complet du fichier (0 bit restant) mais la fonction de découpe lui renvois zéro caractère lue car le premier caractère qu'elle lit est \0 et s’arrête en pensant avoir affaire a la fin de la mémoire
    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
     
     static int decoupeStream(char *buffer,char *output){
        int i=0;
        for(i=0;i<BUFFERSIZE;i++)
        {
            if (!*buffer) break;
            output[i]=*buffer;
            buffer++;
        }
        output[i]='\0';
        return i;
    }
    /** \brief decoupe un buffer en segment de BUFFERSIZE byte
     * destructif
     * \param buffer a decouper
     * \param
     * \return partie du buffer faisant BUFFERSIZE
     */
    je me doute qu'il me faut un autre code pour découper mon fichier mais je vois pas d'autre moyen (une fonction pour verifier si une un pointeur est allouer ca n'existe pas non?)

  13. #13
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Tu penses encore trop en texte. Oublie les \0, pense en terme de pointeur et taille dans un size_t!
    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.

  14. #14
    Membre confirmé
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Mars 2014
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur sécurité

    Informations forums :
    Inscription : Mars 2014
    Messages : 158
    Points : 462
    Points
    462
    Par défaut
    @médinoc tu as raison j'ai remanier des fonctions dont decoupeStream et envoiefile pour ça du coup je ne gérè qu'une taille cependant j'ai un caractére qui ce rajoute (plus q'un ENFIN) à la fin du fichier

    de plus pour les fichier binaire j'ai un bug lors de l'envoie (après le premier fichier envoyer je lis une fois sur mon socket \0 (EDIT decoupeStream renvoyais un buffer trop grand de 1 ce qui entrainais la lecture d'un \0 àprés la fin de l'envoie))
    et pour les binaire
    EDIT après correction de DecoupeStream les binaires sont bien envoyé mais la taille du buffer est toujours 4096 même pour le dernier qui est plus petit
    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
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    #define DEBUG_ENVOIE
    #include "SocketC+S.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define PORT 8888
    #define BUFFERSIZE 4096
    #define TRUE 1
    #define FALSE 0
     
    #ifdef WIN32
    #include <winsock2.h>
    #define DELIMITATEUR '\\'
    #elif defined (linux)
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <errno.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <netdb.h>
    #define INVALID_SOCKET -1
    #define SOCKET_ERROR -1
    #define closesocket(s) close(s)
    #define DELIMITATEUR '/'
    typedef int SOCKET;
    typedef struct sockaddr_in SOCKADDR_IN;
    typedef struct sockaddr SOCKADDR;
    typedef struct in_addr IN_ADDR;
    #else
    #error not defined for this platform
    #endif // WIN32
    static  void init(){
        #ifdef WIN32
        WSADATA wsa;
        int err =WSAStartup⁽MAKEWORD(2, 2),&wsa);
        if(err<0){
            puts("WSAstartup failed !\n");
            exit(EXIT_FAILURE);
        }
        #endif // WIN32
    }
    /** \brief initialisation de l'interface winsock
     * \return void
     */
    static void end(SOCKET sock){
    closesocket(sock);
    #ifdef WIN32
        WSACleanup();
    #endif // WIN32
     
    }
    /** \brief fin de l'interface winsock
     *  fermeture du socket
     * \param socket a fermer (socket principal)
     * \return void
     */
     static void Dsend(char *buffer, SOCKET sock,int size){
     
        if(send(sock,&size,sizeof(int),0)<0){
            perror("send()");
            exit(errno);
        }
        #ifdef DEBUG_ENVOIE
        printf("size: %u\n",size);
        #endif // DEBUG_ENVOIE
        if(send(sock,buffer,strlen(buffer),0)<0){
            perror("send()");
            exit(errno);
        }
        #ifdef DEBUG_ENVOIE
        printf("buffer: '%s'\n",buffer);
        #endif // DEBUG_ENVOIE
    }
    /** \brief envois de la taille du buffer
     *  envois du buffer sur le socket
     * \param buffer a envoyer
     * \param socket sur lequel envoyer
     * \return void
     */
     
    static  char * Drecv(SOCKET csock,int *size){
        if(recv(csock, size,sizeof(int),0)<0){
           perror("recv()");
           exit(errno);
        }
        #ifdef DEBUG_ENVOIE
        printf("size: %u\n",*size);
        #endif // DEBUG_ENVOIE
        char *data=malloc(*size);
        if(recv(csock, data,*size,0)<0){
           perror("recv()");
           exit(errno);
        }int i=*size;
        data[i]='\0';
        #ifdef DEBUG_ENVOIE
        printf("data: '%s'\n",data);
        #endif // DEBUG_ENVOIE
    return data;
    }
    /** \brief reception des infos envoyer par Dsend
     *
     * \param buffer a remplir
     * \param socket client sur lequel ecouter
     * \return taille du buffer
     */
     
     static int Csignal(int buffer,SOCKET sock){
        int res=0;
        if(send(sock,&buffer,sizeof(buffer),0)<0){
            perror("send()");
            exit(errno);
        }
        printf("signal %u sent\n",buffer);
        if(recv(sock, &res,sizeof(int),0)<0){
            perror("recv()");
            exit(errno);
        }
        if(res!=1){
            printf("reponse incorecte\n");
            return FALSE;
        }else{
            return TRUE;
            printf("signal %u recu\n",res);
        }
    }
    /** \brief envoie du signal de choix
     * \param signal a envoyer
     * \param socket sur lequel envoyer
     * \return 0 si reponse incorecte du serveur
     *  1 si reponse correcte du serveur
     */
     
    static int Rsignal(SOCKET sock){
        int buffer=0;
        int res=0;
        if(recv(sock, &res,sizeof(int),0)<0){
            perror("recv()");
            exit(errno);
        }
        switch(res){
        case 1:buffer=1;break;
        case 666:buffer=1;break;
        default:buffer=0;break;
        }
        printf("signal reçu: %u\n",res);
        if(send(sock,&buffer,sizeof(buffer),0)<0){
            perror("send()");
            exit(errno);
        }
        printf("Reponse au signal: %u\n",buffer);
     
        return res;
    }
    /** \brief reception du signal de Csignal
     * \param socket sur lequel recevoir
     * \return valeur du signal
     */
    static FILE *RFopen(char *nomFichier,char *dossier){
     
        char *location=strdup(dossier);
    	if( location == NULL ){
    		perror("Erreur allocation mémoire\n");
    		exit( EXIT_FAILURE );
    	}
        char *ptr_loc=NULL;
        FILE *fichier;
     
        ptr_loc=realloc(location,(strlen(location)+sizeof(nomFichier)+1));
        if( ptr_loc == NULL ){
    		free( location );
    		location = NULL;
    		perror("Erreur reallocation\n");
    		exit( EXIT_FAILURE );
    	}
        location=ptr_loc;
     
        strcat(location,nomFichier);
        fichier=fopen(location,"wb");
        if (fichier==NULL) {
        perror("fopen()");
        exit(errno);
        }else{
            printf("Fichier ouvert: %s \nDans %s\n",nomFichier,dossier);
        }
        free(location);
        return fichier;
    }
    /** \brief ouverture d'un fichier en mode binaire
     * \param nom du fichier
     * \param dossier de stockage du fichier
     * \return file descriptor
     */
     
    static char *chNom(char *input){
        char* carac=input;
        int i;
        char* nom;
        for (i=0; i<128; i++)
        {
            if (!*carac) break;
            nom=carac;
            while(*carac && *carac!=DELIMITATEUR) carac++;
            if (*carac)
            {
                carac++;
            }
        }
        return nom;
    }
    /** \brief recuperation d'un nom de fichier dans un chemin
     * non destructif
     * \param chemin du fichier
     * \param none
     * \return nom du fichier
     */
     
      static void Lerase(){
        printf("\x0d");
        printf("\033[K");
    }
    /** \brief efface la ligne actuel de stdout
     * \param none
     * \param none
     * \return void
     */
     
    static char *readFile(char *path,long *lSize){
        FILE * fichier;
        char * buffer;
        size_t result;
     
        fichier = fopen ( path , "rb" );
        if (fichier==NULL) {
            perror("fopen()");
            exit(errno);
        }
        // obtain file size:
        fseek (fichier , 0 , SEEK_END);
        *lSize = ftell (fichier);
        rewind (fichier);
        // allocate memory to contain the whole file:
        buffer = (char*)malloc(*lSize);
        if (buffer == NULL)  {
            perror("malloc()");
            exit(errno);
            }
      // copy the file into the buffer:
        result = fread (buffer,1,*lSize,fichier);
        if (result != *lSize)  {
            perror("fread()");
            exit(errno);
        }
        /* the whole file is now loaded in the memory buffer. */
        // terminate
        fclose (fichier);
        return buffer;
    }
    /** \brief enregistre un fichier binaire en ram
     * \param chemin du fichier
     * \param none
     * \return pointeur sur le fichier en ram
     */
     
    static long sizeOfFile(char *path){
        long lSize;
        FILE *fichier = fopen ( path , "rb" );
        if (fichier==NULL) {
            perror("fopen()");
            exit(errno);
        }
        fseek (fichier , 0 , SEEK_END);
        lSize = ftell (fichier);
        rewind (fichier);
        fclose(fichier);
        return lSize;
    }
    /** \brief recupere le nombre de byte du fichier
     * \param chemin du fichier
     * \param none
     * \return nombre de byte
     */
     
     static int decoupeStream(char *buffer,char *output,long size,long byteActuel){
        int i=0;
        size=size-byteActuel;
        buffer=buffer+byteActuel;
        for(i=0;i<=BUFFERSIZE;i++)
        {
            if (i>=size) break;
            output[i]=*buffer;
            buffer++;
        }
        output[i]='\0';
        return i;
    }
    /** \brief decoupe un buffer en segment de BUFFERSIZE byte
     * destructif
     * \param buffer a decouper
     * \param
     * \return partie du buffer faisant BUFFERSIZE
     */
     
    static void sFile(char *path,SOCKET sock){
        char* nom=chNom(path);
        long size=0;
        char *file=readFile(path,&size);
        printf("le nom est '%s',le chemin est '%s'\n",nom,path);
        while(!Csignal(1,sock));
     
        if(send(sock,&size,sizeof(long),0)<0){
            perror("send()");
            exit(errno);
        }
            Dsend(nom,sock,strlen(nom));
        envoieFile(path,sock,size,file);
    }
    /** \brief envoie d'un fichier avec prérequis:
     * Csignal; Dsend(nom); envoieFile
     * \param chemin du fichier
     * \param socket sur lequel envoyer
     * \return void
     */
     
    static void envoieFile(char *path ,SOCKET sock,long size,char *file){
        long i=0;
        int sSize=0;
        char *ligne=malloc(BUFFERSIZE);
     
        printf("sending file : %s\n",path);
        for(i=0;size>i;i=i+sSize)
        {
            sSize=decoupeStream(file,ligne,size,i);
            printf(".");
            Dsend(ligne,sock,sSize);
            memset(ligne,'\0',BUFFERSIZE);
        }
        printf("\r\n");
        free(ligne);
        free(file);
    }
    /** \brief envoie du corp d'un fichier
     * \param chemin du fichier
     * \param socket sur lequel envoyer
     * \return void
     */
     
    static void frecv(SOCKET csock,char *dossier){
        int ctrl;
        long size,i=0;
        if(recv(csock, &size,sizeof(long),0)<0){
           perror("recv()");
           exit(errno);
        }
        printf("taille du fichier : %lu Octets\n",size);
        char *buffer=malloc(BUFFERSIZE);
        char *nomFichier=Drecv(csock,&ctrl);
        FILE *fichier=RFopen(nomFichier,dossier);
        for(i=0;i<size;i=i+ctrl)
       {
        free(buffer);
        buffer=Drecv(csock,&ctrl);
        fwrite( buffer , 1 , ctrl, fichier);
        }
        fclose(fichier);
    }
    /** \brief reception d'un fichier
     * nom + corp
     * \param socket sur lequel ecouter
     * \param dossier ou stocker le fichier
     * \return void
     */
     
    static SOCKET Caccept(SOCKET sock){
        SOCKADDR_IN csin= {0};
        SOCKET csock;
        socklen_t sinsize=sizeof(csin);
        csock=accept(sock,(SOCKADDR *)&csin,&sinsize);
        if(csock==INVALID_SOCKET){
            perror("accept()");
            exit(errno);
        }
     return(csock);
    }
    /** \brief creation d'un socket client
     * \param socket initial
     * \param none
     * \return socket client
     */
    voila la dernière version

  15. #15
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Au fait, ils sont bizarres, tes commentaires Doxygen: Il me semblait qu'on était censé les mettre en tête de fonction, et non pas en queue...
    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.

  16. #16
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Première remarque "technique": Je constate que Dsend utilise encore strlen()...
    En fait, Dsend devrait prendre un const void* en paramètre, plutôt qu'un char*, vu que les données transmises peuvent être n'importe quoi et qu'on n'a pas à faire de strlen()...
    (il faudra retirer le printf("%s",), aussi)

    De plus:
    • En fait, il n'y a aucun const dans le code.
    • Tu n'as pas suivi notre conseil de mettre la concaténation via realloc() dans une fonction dédiée.
    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.

  17. #17
    Membre confirmé
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Mars 2014
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur sécurité

    Informations forums :
    Inscription : Mars 2014
    Messages : 158
    Points : 462
    Points
    462
    Par défaut
    @médinoc
    Je constate que Dsend utilise encore strlen()...
    effectivement un oublie de ma part
    de plus

    En fait, il n'y a aucun const dans le code.
    effectivement je n'ai pas encore bien saisie l'utilité des const ...
    et
    Tu n'as pas suivi notre conseil de mettre la concaténation via realloc() dans une fonction dédiée.
    oui je ne l'ai pas fait comme je l'avais dis je m'en chargerais quand j'aurais terminer de debuger le code
    d’ailleurs vu que j'ai un code est fonctionnel pour les binaires aussi je vais m'y atteler

    P.S voila 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
    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
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    #define DEBUG_ENVOIE
    #include "SocketC+S.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define PORT 8888
    #define BUFFERSIZE 4096
    #define TRUE 1
    #define FALSE 0
     
    #ifdef WIN32
    #include <winsock2.h>
    #define DELIMITATEUR '\\'
    #elif defined (linux)
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <errno.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <netdb.h>
    #define INVALID_SOCKET -1
    #define SOCKET_ERROR -1
    #define closesocket(s) close(s)
    #define DELIMITATEUR '/'
    typedef int SOCKET;
    typedef struct sockaddr_in SOCKADDR_IN;
    typedef struct sockaddr SOCKADDR;
    typedef struct in_addr IN_ADDR;
    #else
    #error not defined for this platform
    #endif // WIN32
    static  void init(){
        #ifdef WIN32
        WSADATA wsa;
        int err =WSAStartup⁽MAKEWORD(2, 2),&wsa);
        if(err<0){
            puts("WSAstartup failed !\n");
            exit(EXIT_FAILURE);
        }
        #endif // WIN32
    }
    /** \brief initialisation de l'interface winsock
     * \return void
     */
    static void end(SOCKET sock){
    closesocket(sock);
    #ifdef WIN32
        WSACleanup();
    #endif // WIN32
     
    }
    /** \brief fin de l'interface winsock
     *  fermeture du socket
     * \param socket a fermer (socket principal)
     * \return void
     */
     static void Dsend(const void * buffer, SOCKET sock,int size){
     
        if(send(sock,&size,sizeof(int),0)<0){
            perror("send()");
            exit(errno);
        }
        #ifdef DEBUG_ENVOIE
        printf("size: %u\n",size);
        #endif // DEBUG_ENVOIE
        if(send(sock,buffer,size,0)<0){
            perror("send()");
            exit(errno);
        }
    }
    /** \brief envois de la taille du buffer
     *  envois du buffer sur le socket
     * \param buffer a envoyer
     * \param socket sur lequel envoyer
     * \return void
     */
     
    static  char * Drecv(SOCKET csock,int *size){
        if(recv(csock, size,sizeof(int),0)<0){
           perror("recv()");
           exit(errno);
        }
        #ifdef DEBUG_ENVOIE
        printf("size: %u\n",*size);
        #endif // DEBUG_ENVOIE
        char *data=malloc(*size);
        if(recv(csock, data,*size,0)<0){
           perror("recv()");
           exit(errno);
        }int i=*size;
        data[i]='\0';
        #ifdef DEBUG_ENVOIE
        printf("data: '%s'\n",data);
        #endif // DEBUG_ENVOIE
    return data;
    }
    /** \brief reception des infos envoyer par Dsend
     *
     * \param buffer a remplir
     * \param socket client sur lequel ecouter
     * \return taille du buffer
     */
     
     static int Csignal(int buffer,SOCKET sock){
        int res=0;
        if(send(sock,&buffer,sizeof(buffer),0)<0){
            perror("send()");
            exit(errno);
        }
        printf("signal %u sent\n",buffer);
        if(recv(sock, &res,sizeof(int),0)<0){
            perror("recv()");
            exit(errno);
        }
        if(res!=1){
            printf("reponse incorecte\n");
            return FALSE;
        }else{
            return TRUE;
            printf("signal %u recu\n",res);
        }
    }
    /** \brief envoie du signal de choix
     * \param signal a envoyer
     * \param socket sur lequel envoyer
     * \return 0 si reponse incorecte du serveur
     *  1 si reponse correcte du serveur
     */
     
    static int Rsignal(SOCKET sock){
        int buffer=0;
        int res=0;
        if(recv(sock, &res,sizeof(int),0)<0){
            perror("recv()");
            exit(errno);
        }
        switch(res){
        case 1:buffer=1;break;
        case 666:buffer=1;break;
        default:buffer=0;break;
        }
        printf("signal reçu: %u\n",res);
        if(send(sock,&buffer,sizeof(buffer),0)<0){
            perror("send()");
            exit(errno);
        }
        printf("Reponse au signal: %u\n",buffer);
     
        return res;
    }
    /** \brief reception du signal de Csignal
     * \param socket sur lequel recevoir
     * \return valeur du signal
     */
    static FILE *RFopen(char *nomFichier,char *dossier){
     
        char *location=strdup(dossier);
    	if( location == NULL ){
    		perror("Erreur allocation mémoire\n");
    		exit( EXIT_FAILURE );
    	}
        char *ptr_loc=NULL;
        FILE *fichier;
     
        ptr_loc=realloc(location,(strlen(location)+sizeof(nomFichier)+1));
        if( ptr_loc == NULL ){
    		free( location );
    		location = NULL;
    		perror("Erreur reallocation\n");
    		exit( EXIT_FAILURE );
    	}
        location=ptr_loc;
     
        strcat(location,nomFichier);
        fichier=fopen(location,"wb");
        if (fichier==NULL) {
        perror("fopen()");
        exit(errno);
        }else{
            printf("Fichier ouvert: %s \nDans %s\n",nomFichier,dossier);
        }
        free(location);
        return fichier;
    }
    /** \brief ouverture d'un fichier en mode binaire
     * \param nom du fichier
     * \param dossier de stockage du fichier
     * \return file descriptor
     */
     
    static char *chNom(char *input){
        char* carac=input;
        int i;
        char* nom;
        for (i=0; i<128; i++)
        {
            if (!*carac) break;
            nom=carac;
            while(*carac && *carac!=DELIMITATEUR) carac++;
            if (*carac)
            {
                carac++;
            }
        }
        return nom;
    }
    /** \brief recuperation d'un nom de fichier dans un chemin
     * non destructif
     * \param chemin du fichier
     * \param none
     * \return nom du fichier
     */
     
      static void Lerase(){
        printf("\x0d");
        printf("\033[K");
    }
    /** \brief efface la ligne actuel de stdout
     * \param none
     * \param none
     * \return void
     */
     
    static char *readFile(char *path,long *lSize){
        FILE * fichier;
        char * buffer;
        size_t result;
     
        fichier = fopen ( path , "rb" );
        if (fichier==NULL) {
            perror("fopen()");
            exit(errno);
        }
        // obtain file size:
        fseek (fichier , 0 , SEEK_END);
        *lSize = ftell (fichier);
        rewind (fichier);
        // allocate memory to contain the whole file:
        buffer = (char*)malloc(*lSize);
        if (buffer == NULL)  {
            perror("malloc()");
            exit(errno);
            }
      // copy the file into the buffer:
        result = fread (buffer,1,*lSize,fichier);
        if (result != *lSize)  {
            perror("fread()");
            exit(errno);
        }
        /* the whole file is now loaded in the memory buffer. */
        // terminate
        fclose (fichier);
        return buffer;
    }
    /** \brief enregistre un fichier binaire en ram
     * \param chemin du fichier
     * \param none
     * \return pointeur sur le fichier en ram
     */
     
    static long sizeOfFile(char *path){
        long lSize;
        FILE *fichier = fopen ( path , "rb" );
        if (fichier==NULL) {
            perror("fopen()");
            exit(errno);
        }
        fseek (fichier , 0 , SEEK_END);
        lSize = ftell (fichier);
        rewind (fichier);
        fclose(fichier);
        return lSize;
    }
    /** \brief recupere le nombre de byte du fichier
     * \param chemin du fichier
     * \param none
     * \return nombre de byte
     */
     
     static int decoupeStream(char *buffer,char *output,long size,long byteActuel){
        int i=0;
        size=size-byteActuel;
        buffer=buffer+byteActuel;
        for(i=0;i<=BUFFERSIZE;i++)
        {
            if (i>=size) break;
            output[i]=*buffer;
            buffer++;
        }
        output[i]='\0';
        return i;
    }
    /** \brief decoupe un buffer en segment de BUFFERSIZE byte
     * destructif
     * \param buffer a decouper
     * \param
     * \return partie du buffer faisant BUFFERSIZE
     */
     
    static void sFile(char *path,SOCKET sock){
        char* nom=chNom(path);
        long size=0;
        char *file=readFile(path,&size);
        printf("le nom est '%s',le chemin est '%s'\n",nom,path);
        while(!Csignal(1,sock));
     
        if(send(sock,&size,sizeof(long),0)<0){
            perror("send()");
            exit(errno);
        }
            Dsend(nom,sock,strlen(nom));
        envoieFile(path,sock,size,file);
    }
    /** \brief envoie d'un fichier avec prérequis:
     * Csignal; Dsend(nom); envoieFile
     * \param chemin du fichier
     * \param socket sur lequel envoyer
     * \return void
     */
     
    static void envoieFile(char *path ,SOCKET sock,long size,char *file){
        long i=0;
        int sSize=0;
        char *ligne=malloc(BUFFERSIZE);
     
        printf("sending file : %s\n",path);
        for(i=0;size>i;i=i+sSize)
        {
            sSize=decoupeStream(file,ligne,size,i);
            printf(".");
            Dsend(ligne,sock,sSize);
            memset(ligne,'\0',BUFFERSIZE);
        }
        printf("\r\n");
        free(ligne);
        free(file);
    }
    /** \brief envoie du corp d'un fichier
     * \param chemin du fichier
     * \param socket sur lequel envoyer
     * \return void
     */
     
    static void frecv(SOCKET csock,char *dossier){
        int ctrl;
        long size,i=0;
        if(recv(csock, &size,sizeof(long),0)<0){
           perror("recv()");
           exit(errno);
        }
        printf("taille du fichier : %lu Octets\n",size);
        char *buffer=malloc(BUFFERSIZE);
        char *nomFichier=Drecv(csock,&ctrl);
        FILE *fichier=RFopen(nomFichier,dossier);
        for(i=0;i<size;i=i+ctrl)
       {
        free(buffer);
        buffer=Drecv(csock,&ctrl);
        fwrite( buffer , 1 , ctrl, fichier);
        }
        fclose(fichier);
    }
    /** \brief reception d'un fichier
     * nom + corp
     * \param socket sur lequel ecouter
     * \param dossier ou stocker le fichier
     * \return void
     */
     
    static SOCKET Caccept(SOCKET sock){
        SOCKADDR_IN csin= {0};
        SOCKET csock;
        socklen_t sinsize=sizeof(csin);
        csock=accept(sock,(SOCKADDR *)&csin,&sinsize);
        if(csock==INVALID_SOCKET){
            perror("accept()");
            exit(errno);
        }
     return(csock);
    }
    /** \brief creation d'un socket client
     * \param socket initial
     * \param none
     * \return socket client
     */

  18. #18
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 186
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 186
    Points : 17 126
    Points
    17 126
    Par défaut
    les pointeurs sur const permettent de ne pas modifier la valeur pointée, et donc d'éviter tout un tas de problèmes.

    Entre autre, "bonjour" est un const char*, il n'est pas possible d'y accéder correctement avec un char*.
    Du coup, une fonction qui prend en argument une chaine constante pourra être utilisé avec un litéral.

    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
    void pasbo(char* str) {
        if (str[0]) ++(str[0]);
    }
     
    void joli(char const* str);//ou const char*
     
     
    int main() {
        joli("une phrase");
     
        char bidule[] = "bidule";
        pasbo(bidule);
     
        pasbo("une phrase");//ATTENTION
        return 0;
    }
    pasbo("une phrase") est compilable (mais lève un warning).
    Le code de pasbo modifie la valeur pointé, cela provoquera une erreur de segmentation, parce que "une phrase" est dans un segment mémoire non modifiable (comme toutes les chaines litérales)


    Quant à la différence entre débugger et nettoyer, sache qu'un code propre est moins buggé, car il ne fait pas deux fois la même chose.
    Il y a donc moins de sources d'erreurs.
    Et surtout, si une erreur est présente dans une fonctionalité, elle est systématique, donc très visibles
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  19. #19
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Dans Drecv():
    Code très mauvais : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int i=*size;
        data[i]='\0';
        #ifdef DEBUG_ENVOIE
        printf("data: '%s'\n",data);
        #endif // DEBUG_ENVOIE
    Tu t'obstines à prendre des données brutes pour des chaînes!

    Et en plus, ton data[i]= déborde du buffer alloué par malloc().

    PS: Tu n'as pas répondu pour les commentaires Doxygen...
    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.

  20. #20
    Membre confirmé
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Mars 2014
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur sécurité

    Informations forums :
    Inscription : Mars 2014
    Messages : 158
    Points : 462
    Points
    462
    Par défaut
    @leternel je n'ai pas bien compris une chose si j'ai
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    const char *p_data="blabla";
    p_data++;
    *p_data="C";
    p_data est non modifiable au niveaux du pointeur ou du contenue

    @médinoc
    Tu t'obstines à prendre des données brutes pour des chaînes!
    excuse moi ce n'est pas mon intention
    j'ai donc penser à ça :
    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
     
     
    static void * Drecv(SOCKET csock,int *size){
        if(recv(csock, size,sizeof(int),0)<0){
           perror("recv()");
           exit(errno);
        }
        #ifdef DEBUG_ENVOIE
        printf("size: %u\n",*size);
        #endif // DEBUG_ENVOIE
        void *data=malloc(*size);
        if(recv(csock, data,*size,0)<0){
           perror("recv()");
           exit(errno);
        }
        return data;
    }
    /** \brief reception des infos envoyer par Dsend
     *
     * \param buffer a remplir
     * \param socket client sur lequel ecouter
     * \return taille du buffer
     */
    mais du coup lorsque je reçois le nom qui lui est une chaines comment lui remettre le \0?
    j’étudie deux possibilités :
    envoyer le nom et la taille dans une structure (vu que je renvois maintenant un pointeur non typé je devrais pouvoir le faire non ?)
    reconstruire la chaine reçue pour le nom (lui rajouter \0 à la fin?)

    laquelle vous semble mieux ?
    P.S le buffer overflow est corrigé avec le nouveaux Drecv non?
    PP.S pour "doxigen" je ne savais même pas que ça appelais comme ça
    en fait comme c'est intégré à codeblock je l'ai utilisé sans savoir qu'il s’agissait d'une norme spécifique
    je pensais juste qu'il s’agissait de block de commentaire un peu comme avec VS (lorsque j'utilisais du c# ) mais je ne savais pas qu'il fallait les mettre aux début (avant la fonction ou à la première ligne de celle ci?)

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [7][Expert Sous-état] Liaison avec le fichier incorrecte
    Par clementratel dans le forum SAP Crystal Reports
    Réponses: 2
    Dernier message: 18/01/2008, 15h12
  2. Numero de fichier incorrect
    Par choko62 dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 20/06/2007, 15h09
  3. Pb création Image (nom Fichier incorrecte)
    Par yocks dans le forum Java ME
    Réponses: 3
    Dernier message: 12/06/2007, 17h58
  4. Réponses: 1
    Dernier message: 22/01/2007, 10h02
  5. [Unix KSH] Ajout caractère fin de ligne dans fichier
    Par -COil- dans le forum Autres langages
    Réponses: 1
    Dernier message: 04/05/2006, 17h06

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