IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Problème lors de l'envoi d'une matrice par socket


Sujet :

C

  1. #21
    Futur Membre du Club Avatar de Blackbelt_29
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2016
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2016
    Messages : 19
    Points : 9
    Points
    9
    Par défaut
    Citation Envoyé par Matt_Houston Voir le message
    Je ne vais pas pérorer que j'te l'avais bien dit voici quelques semaines mais bon..
    c'est vrai,mais je pensais qu'une fois le tableau bien alloué c'était pas plus difficile

    Citation Envoyé par Médinoc Voir le message
    Attention, ajouter un offset à un pointeur ajoute l'offset multiplié par la taille de la donnée pointée.

    Ou sinon, je considère directement mon buffer comme un tableau de bytes.
    du coup je dois faire quelque chose du genre pBytes =OffsetInBytes(void* pv, ptrdiff_t offset);, mais je vois pas trop à quoi correspondent les variables passées en paramètres :/ ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
        long int nombre=0;
        long int *pBytes=&nombre;
        pBytes =OffsetInBytes(void* pv, ptrdiff_t offset);
    Pour les erreurs quand je fais étape par étapes avec le debug voici ce que j'obtiens :

    Avant de rentrer dans le while (donc avant la réception)
    => offset = 0
    => retval pas encore définit

    je rentre dans le while:
    => retval = 993152 qui est supérieur à '0' donc offset = 993152

    2ème boucle :
    => retval=-1 (erreur)

    Je sors de ma boucle j'affiche 'erreur' et je termine mon programme.

    En fait quand je passe en mode debug on voit bien que le programme termine correctement avant de m'envoyer l'erreur *** stack smashing detected ***: ./client terminated

  2. #22
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Citation Envoyé par Blackbelt_29 Voir le message
    c'est vrai,mais je pensais qu'une fois le tableau bien alloué c'était pas plus difficile
    Et tu avais raison, jusqu'à ce qu'il te faille envoyer tout ça sur le réseau. À noter que la disposition mémoire exposée par Médinoc permet d'avoir le meilleur des deux mondes au prix d'un modeste apport de complexité.


    Citation Envoyé par Blackbelt_29 Voir le message
    du coup je dois faire quelque chose du genre pBytes =OffsetInBytes(void* pv, ptrdiff_t offset);, mais je vois pas trop à quoi correspondent les variables passées en paramètres :/ ?
    pv correspond à l'adresse de base (celle de ta matrice) et offset au décalage à effectuer, en bytes / chars / « octets ».


    Si p est un pointeur (valide) vers un type quelconque et offset contient une valeur entière alors p + offset == (char *)p + offset * sizeof(*p) est toujours vérifié. Mais dans ce contexte, l'offset exprime un nombre d'éléments (de taille sizeof(*p)), hors recv attend un décalage en bytes (puisque c'est le type « générique » en C). Il faut donc effectuer une conversion soit directement lors de l'appel, soit via la routine de Médinoc.

  3. #23
    Futur Membre du Club Avatar de Blackbelt_29
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2016
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2016
    Messages : 19
    Points : 9
    Points
    9
    Par défaut
    Du coup si j'ai bien compris dans mon cas la taille de l'offset sera égale a sizeof(float) ?

    au final si j'appelle la fonction de Médinoc je devrais le faire de cette façon :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
            long int nombre=0;
            long int *pBytes=&nombre;
            pBytes =OffsetInBytes(NewImage.tabImage, sizeof(float);
    Le première élément correspondant à ma matrice et le deuxième à la taille du décalage à effectuer

    Je précise que le vecteur présent dans ma structure est de la forme float *tabImage;

    et du coup je dois recevoir de cette façon :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	retVal = recv(sock,((char *)&NewImage.tabImage[0])+pBytes, 512*512*sizeof(float)-pBytes, 0);

  4. #24
    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 519
    Points
    41 519
    Par défaut
    Non, plutôt un truc de ce genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    retVal = recv(sock, OffsetInBytes(&NewImage.tabImage[0][0], tailleDejaRecue), tailleTotaleEnBytes-tailleDejaRecue, 0);
    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. #25
    Membre expérimenté
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    Par défaut
    Bonjour
    Citation Envoyé par Blackbelt_29 Voir le message
    Bonjour,

    J'essaye d'envoyer une matrice de float (tableau à deux dimensions) par socket, avec les cours sur internet j'arrive bien à envoyer d'un client vers un serveur une chaine de caractère ainsi que des structures. Du coup mon idée était justement d'utiliser des structures afin d'envoyer mon tableau à deux dimensions. Du coup je crée un tableau 2*2 que je copie dans ma structure et je l'envoie. Le problème est que quand j'essaye de la récupérer j'ai une erreur de segmentation, et je ne vois absolument pas d'où ça peut venir ?


    Voici le code en question du côté serveur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    //Création de la structure
        typedef struct Image Image;
    struct Image{
        float** tabImage;
    };
     
        float **tab2=NULL;
    tab2=allocation(2,2);
    tab2[0][0]=2.0;
    tab2[0][1]=4.32;
        tab2[1][0]=1.47;
        tab2[1][1]=8.37;
     
    Image NewImage;
    NewImage.tabImage=allocation(2,2);//Fonction qui alloue dynamiquement la matrice
    int i,j;
     
         //Recopie les valeurs de tab2 dans la structure
     
         for(i=0;i<2;i++)
        for(j=0;j<2;j++)
            NewImage.tabImage[i][j]=tab2[i][j];
     
         //Envoie la structure
     sock_err = send(csock,&NewImage,sizeof(NewImage), 0);


    Et voici le code en question côté client
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    /*Déclaration de la structure coté client
    typedef struct Image Image;
        struct Image{
            float** tabImage;
        };
     
        Image NewImage;
        NewImage.tabImage=allocation(2,2); //allocation  dynamique du tableau
        recv(sock,&NewImage.tabImage ,sizeof(NewImage), 0);
    //Reception de la structure
    Je n'ai pas mis le reste de la fonction car je pense que l'erreur vient de ces lignes (car ça marche bien sinon avec une chaine de caractère ou une structure avec des int, double...),mais si il faut je la mettrai sans problème !

    Merci !

    « Send » peut envoyer une structure à condition que la structure ne contienne que les types de bases (c’est à dire des champs sans pointeur ou pointeur sur bidule) et dans ce cas, l’envoi de la structure peut se faire aisément en passant à « send() » l'adresse de votre structure en question et sa taille.
    Dans le cas où les champs de votre structure sont composés de pointeurs, il faut envoyer les données pointées par le pointeur en question. Parce que si vous envoyez le pointeur, vous ne faites qu’envoyer la valeur du pointeur : en clair là ou pointe votre pointeur donc son adresse.
    Mais attention, si vos tests avec envoi de structure dont les champs contiennent des pointeurs fonctionnent, c’est parce que serveur et client sont sur la même machine. Dans le cas où le serveur est sur une autre machine que celle du client, cela ne marchera pas pour les raisons que j’ai énoncé précédemment.

    Cependant, je me permets toute de même de vous poser la question suivante : pourquoi souhaitez-vous envoyer systématiquement une structure avec un champ qui est un pointeur sur quelque chose ?
    à bientôt
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

  6. #26
    Futur Membre du Club Avatar de Blackbelt_29
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2016
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2016
    Messages : 19
    Points : 9
    Points
    9
    Par défaut
    Après 2 jours de codage intense j'ai finalement rechangé ma façon de pense, j'ai l'impression que ça avance mais j'ai toujours des soucis

    Mon idée est de rester avec des chars (que je sais envoyer et recevoir) et donc transmettre un tableau de char. Pour ce faire j'ai donc transformé mon image (ma matrice 512*512) au format .bmp. Ensuite je récupère l'entête du fichier de mon image afin de prendre les informations intéressantes (largueur, longueur et taille) jusque-là y a pas de soucis ça fonctionne très bien. Ensuite j'ouvre mon image grâce à fread dans un tableau de char et je l'envoie. Sur le papier ça me paraissait simple, mais en fait pas du tout !Le problème est qu'a la réception bien que j'aie la même taille que lors de l'envoi et les mêmes longueurs/largeur lorsque je l'affiche je n'ai qu'une partie de l'image :/
    Du coup vu que j'ai la même taille à la réception et les mêmes longueur et largeur je pense que l'envoi se fait bien, du coup je ne vois absolument pas d'où l'erreur peut venir

    Nom : reception.jpg
Affichages : 419
Taille : 60,4 Ko

    Voici le code que j'ai fait du côté serveur (il est moche mais je l'arrangerais dès que tout fonctionne ) j'ai essayé de commenter au maximum afin de vous aider à comprendre ma démarche !

    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
    #if defined (WIN32)
        #include <winsock2.h>
        typedef int socklen_t;
    #elif defined (linux)
        #include <sys/types.h>
        #include <sys/socket.h>
        #include <netinet/in.h>
        #include <arpa/inet.h>
        #include <unistd.h>
        #define INVALID_SOCKET -1
        #define SOCKET_ERROR -1
        #define closesocket(s) close(s)
        typedef int SOCKET;
        typedef struct sockaddr_in SOCKADDR_IN;
        typedef struct sockaddr SOCKADDR;
    #endif
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define PORT 1025
     
    /*--------------------------------------------------*/
    /*   Structure pour lire l'en-tête du fichier bmp   */
    /*--------------------------------------------------*/
     struct entete_struct {
    	char signature[2];
    	int taille;
    	int offset;
    	int taille_entete;
    	int largeur;
    	int longueur;
    	int plans;
    	int bpp;
    	int compression;
    	int taille_image;
    	int Hresolution;
    	int Vresolution;
    	int nbr_couleur;
    	int nbr_couleur_importante;
    }entete;
     
    /*---------------------------------------------*/
    /*  Converison de l'en-tête de l'hexa en deci  */
    /*---------------------------------------------*/
    int hex2dec (unsigned char hex[4],int nombre)
    {
    	int resultat = 0;
    	int i;
    	for (i = nombre - 1; i >= 0; i--)
    		resultat = resultat * 256 + hex[i];
     
       return resultat;
    }
     
    /*--------------------------------------------*/
    /*	    Lecture de l'en-tête	      */
    /*--------------------------------------------*/
    void lire_fichier ()
    {
    	unsigned char temp[4];
    	FILE * fichier;
            fichier = fopen("/home/elric/Images/ImageTraitement.bmp", "r");
     
            if (fichier == NULL)
            {
                printf("impossible d'ouvrir le fichier\n");
                exit(0);
            }
    	fread (&entete.signature,2,1,fichier);
    	fread (&temp,4,1,fichier);
    	entete.taille = hex2dec (temp,4);
    	fread (&temp,4,1,fichier);
    	fread (&temp,4,1,fichier);
    	entete.offset = hex2dec (temp,4);
    	fread (&temp,4,1,fichier);
    	entete.taille_entete = hex2dec (temp,4);
    	fread (&temp,4,1,fichier);
    	entete.largeur = hex2dec(temp,4);
    	fread (&temp,4,1,fichier);
    	entete.longueur = hex2dec(temp,4);
    	fread (&temp,2,1,fichier);
    	entete.plans = hex2dec (temp,2);
    	fread (&temp,2,1,fichier);
    	entete.bpp = hex2dec (temp,2);
    	fread (&temp,4,1,fichier);
    	entete.compression = hex2dec (temp,4);
    	fread (&temp,4,1,fichier);
    	entete.taille_image = hex2dec (temp,4);
    	fread (&temp,4,1,fichier);
    	entete.Hresolution = hex2dec (temp,4);
    	fread (&temp,4,1,fichier);
    	entete.Vresolution = hex2dec (temp,4);
    	fread (&temp,4,1,fichier);
    	entete.nbr_couleur = hex2dec (temp,4);
    	fread (&temp,4,1,fichier);
    	entete.nbr_couleur_importante = hex2dec (temp,4);
     
    	fclose (fichier);
    }
     
    /*---------------------------------------------*/
    /*		fichier main 		       */
    /*---------------------------------------------*/
     
    int main(void)
    {
        lire_fichier ();//Lecture du header 
        printf ("Taille du fichier à envoyer : %d\n",entete.taille);
        printf ("Largeur : %d\n",entete.largeur);
        printf ("Longueur : %d\n",entete.longueur);
     
        /* Je lis l'image et la stock dans mon tableau de char*/
        FILE * fic_image;
        fic_image = fopen("/home/elric/Images/ImageTraitement.bmp", "r");
     
        if (fic_image == NULL){
    		printf("Error unable to open image\n");
    		exit(0);
        }
        unsigned char bitmapImage_envoi[entete.taille*sizeof(char)];  
        fread(bitmapImage_envoi,sizeof(char),entete.taille,fic_image);
        fclose(fic_image);
        /*-----*/
     
     
        /* j'enregistre l'image pour voir si l'image envoye est correct*/
        FILE * fic_image_E;
        fic_image_E = fopen("/home/elric/Images/envoie/imageEnvoyee.bmp","wb");
        if (fic_image_E == NULL){
            printf("Error unable to write the image\n");
        exit(0);
        }
     
        fwrite(bitmapImage_envoi,1024*sizeof(char),510*511,fic_image_E);
        fclose(fic_image_E);
        /*----*/
     
     
        #if defined (WIN32)
            WSADATA WSAData;
            int erreur = WSAStartup(MAKEWORD(2,2), &WSAData);
        #else
            int erreur = 0;
        #endif
     
        SOCKET sock;
        SOCKADDR_IN sin;
        SOCKET csock;
        SOCKADDR_IN csin;
        socklen_t recsize = sizeof(csin);
        int sock_err;
     
        /* Si les sockets Windows fonctionnent */
        if(!erreur)
        {
            sock = socket(AF_INET, SOCK_STREAM, 0);
     
            /* Si la socket est valide */
            if(sock != INVALID_SOCKET)
            {
                printf("La socket %d est maintenant ouverte en mode TCP/IP\n", sock);
     
                /* Configuration */
                sin.sin_addr.s_addr    = htonl(INADDR_ANY);   /* Adresse IP automatique */
                sin.sin_family         = AF_INET;             /* Protocole familial (IP) */
                sin.sin_port           = htons(PORT);         /* Listage du port */
                sock_err = bind(sock, (SOCKADDR*)&sin, sizeof(sin));
     
                /* Si la socket fonctionne */
                if(sock_err != SOCKET_ERROR)
                {
                    /* Démarrage du listage (mode server) */
                    sock_err = listen(sock, 5);
                    printf("Listage du port %d...\n", PORT);
     
                    /* Si la socket fonctionne */
                    if(sock_err != SOCKET_ERROR)
                    {
                        /* Attente pendant laquelle le client se connecte */
                        printf("Patientez pendant que le client se connecte sur le port %d...\n", PORT);        
     
                        csock = accept(sock, (SOCKADDR*)&csin, &recsize);
                        printf("Un client se connecte avec la socket %d de %s:%d\n", csock, inet_ntoa(csin.sin_addr), htons(csin.sin_port));
     
    		/*ENVOI DE L'IMAGE*/
                        sock_err = send(csock, bitmapImage_envoi,510*511, 0);
     
                        if(sock_err != SOCKET_ERROR)
                            printf("Chaine envoyée");
                        else
                            printf("Erreur de transmission\n");
     
                        /* Il ne faut pas oublier de fermer la connexion (fermée dans les deux sens) */
                        shutdown(csock, 2);
                    }
                }
     
                /* Fermeture de la socket */
                printf("Fermeture de la socket...\n");
                closesocket(sock);
                printf("Fermeture du serveur terminee\n");
            }
     
            #if defined (WIN32)
                WSACleanup();
            #endif
        }
     
       return EXIT_SUCCESS;
    }

    et le code coté client :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    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
    #if defined (WIN32)
        #include <winsock2.h>
        typedef int socklen_t;
    #elif defined (linux)
        #include <sys/types.h>
        #include <sys/socket.h>
        #include <netinet/in.h>
        #include <arpa/inet.h>
        #include <unistd.h>
        #define INVALID_SOCKET -1
        #define SOCKET_ERROR -1
        #define closesocket(s) close(s)
        typedef int SOCKET;
        typedef struct sockaddr_in SOCKADDR_IN;
        typedef struct sockaddr SOCKADDR;
    #endif
     
    #include <opencv2/core/core.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <stdexcept>
    #include <cmath>
    #include <stdio.h>
    #include<string.h>
    #include <stdlib.h>
    #include<iostream>
    #include<valarray>
    #include <unistd.h>
    using namespace cv;
    using namespace std;
    #define PORT 1025
     
    struct entete_struct {
    	char signature[2];
    	int taille;
    	int offset;
    	int taille_entete;
    	int largeur;
    	int longueur;
    	int plans;
    	int bpp;
    	int compression;
    	int taille_image;
    	int Hresolution;
    	int Vresolution;
    	int nbr_couleur;
    	int nbr_couleur_importante;
    }entete;
     
    int hex2dec (unsigned char hex[4],int nombre)
    {
    	int resultat = 0;
    	int i;
    	for (i = nombre - 1; i >= 0; i--)
    		resultat = resultat * 256 + hex[i];
     
       return resultat;
    }
     
    void lire_fichier ()
    {
    	unsigned char temp[4];
    	FILE * fichier;
            fichier = fopen("/home/elric/Images/reception/New_image.bmp", "r");
     
            if (fichier == NULL)
            {
                printf("impossible d'ouvrir le fichier\n");
                exit(0);
            }
    	fread (&entete.signature,2,1,fichier);
    	fread (&temp,4,1,fichier);
    	entete.taille = hex2dec (temp,4);
    	fread (&temp,4,1,fichier);
    	fread (&temp,4,1,fichier);
    	entete.offset = hex2dec (temp,4);
    	fread (&temp,4,1,fichier);
    	entete.taille_entete = hex2dec (temp,4);
    	fread (&temp,4,1,fichier);
    	entete.largeur = hex2dec(temp,4);
    	fread (&temp,4,1,fichier);
    	entete.longueur = hex2dec(temp,4);
    	fread (&temp,2,1,fichier);
    	entete.plans = hex2dec (temp,2);
    	fread (&temp,2,1,fichier);
    	entete.bpp = hex2dec (temp,2);
    	fread (&temp,4,1,fichier);
    	entete.compression = hex2dec (temp,4);
    	fread (&temp,4,1,fichier);
    	entete.taille_image = hex2dec (temp,4);
    	fread (&temp,4,1,fichier);
    	entete.Hresolution = hex2dec (temp,4);
    	fread (&temp,4,1,fichier);
    	entete.Vresolution = hex2dec (temp,4);
    	fread (&temp,4,1,fichier);
    	entete.nbr_couleur = hex2dec (temp,4);
    	fread (&temp,4,1,fichier);
    	entete.nbr_couleur_importante = hex2dec (temp,4);
     
    	fclose (fichier);
    }
     
     
    int main(void)
    {
        char bitmapImage_reception[512*512];
        //bitmapImage_reception = (unsigned char*)malloc(512*512*sizeof(char));
     
        #if defined (WIN32)
            WSADATA WSAData;
            int erreur = WSAStartup(MAKEWORD(2,2), &WSAData);
        #else
            int erreur = 0;
        #endif
     
        SOCKET sock;
        SOCKADDR_IN sin;
     
        /* Si les sockets Windows fonctionnent */
        if(!erreur)
        {
            /* Création de la socket */
            sock = socket(AF_INET, SOCK_STREAM, 0);
     
            /* Configuration de la connexion */
            sin.sin_addr.s_addr = inet_addr("127.0.0.1");
            sin.sin_family = AF_INET;
            sin.sin_port = htons(PORT);
     
            /* Si l'on a réussi à se connecter */
            if(connect(sock, (SOCKADDR*)&sin, sizeof(sin)) != SOCKET_ERROR)
            {
                printf("Connection à %s sur le port %d\n", inet_ntoa(sin.sin_addr), htons(sin.sin_port));
     
                /* Si l'on reçoit des informations : on les affiche à l'écran */
                if(recv(sock, bitmapImage_reception, 512*512*sizeof(char), 0) != SOCKET_ERROR){
                printf("Recu\n");
                  //  ecriture_imageBMP(bitmapImage_reception);
     
                    /* je sauvegarde l'image reçu */
                    FILE * fic_image_R;
                    fic_image_R = fopen("/home/elric/Images/reception/New_image.bmp","wb");
                    if (fic_image_R == NULL){
                        printf("Error unable to write the image\n");
                        exit(0);
                    }
                    fwrite(bitmapImage_reception,sizeof(char),512*512,fic_image_R);
                    fclose(fic_image_R);
                    /*----*/
     
                   /*J'affiche les informations de l'image*/
                   lire_fichier ();
                   printf ("Taille du fichier : %d\n",entete.taille);
                   printf ("Largeur : %d\n",entete.largeur);
                   printf ("Longueur : %d\n",entete.longueur);
                   /*----*/
     
                  /*J'affiche directement mon image (pas vraiment utile ici*/
                  Mat img1 = imread("/home/elric/Images/reception/New_image.bmp");
                  imshow("newImage",img1);
                  waitKey();
                  /*---*/
                }
            }
            /* sinon, on affiche "Impossible de se connecter" */
            else
            {
                printf("Impossible de se connecter\n");
            }
     
            /* On ferme la socket */
            closesocket(sock);
     
            #if defined (WIN32)
                WSACleanup();
            #endif
        }
     
     
        return EXIT_SUCCESS;
    }
    Et voilà ce qu'affiche mon terminal :
    Nom : terminal.jpg
Affichages : 422
Taille : 45,8 Ko

  7. #27
    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 519
    Points
    41 519
    Par défaut
    Pourquoi envoies-tu 510*511?
    Tu devrais envoyer Arrondir4Sup(entete.largeur) * entete.hauteur * (entete.bpp/8)...

    Avec la fonction Arrondir4Sup() définie comme suit, pour arrondir aux quatre octets supérieurs (contrainte d'alignement du format bmp):
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int Arrondir4Sup(int n)
    {
    	/*La formule classique, ce serait diviser par la "taille de morceau"
    	  en arrondissant à l'unité supérieure, puis multiplier à nouveau.
    	  Mais pour une puissance de deux, c'est beaucoup plus facile:*/
    	return (n+3) & (~3);
    }
    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.

  8. #28
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    J'ai lu très en diagonale mais : tu ouvres ton BMP, tu en parcours l'en-tête pour obtenir la taille de la matrice, puis tu le refermes. Ensuite, tu l'ouvres à nouveau pour récupérer les données des pixels (ligne 122 du code serveur) mais tu n'avances pas le curseur au préalable. Tu copies donc à partir de l'en-tête. Lorsque tu ouvres un fichier, le curseur est à zéro.

    Je m'interroge également comme Médinoc sur la signification de ce 510*511...

    Tu peux remplacer toutes les occurrences de sizeof(char) par 1, c'est garanti.

  9. #29
    Futur Membre du Club Avatar de Blackbelt_29
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2016
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2016
    Messages : 19
    Points : 9
    Points
    9
    Par défaut
    Pour le 510*511 c'est parce que j'avais testé sur une autre image (de taille 510*511) mais lors de mes tests pour Lena j'avais bien mis 512*512 !

    Citation Envoyé par Matt_Houston Voir le message
    Tu copies donc à partir de l'en-tête.[/b] Lorsque tu ouvres un fichier, le curseur est à zéro.
    comment fait-on du coup pour lire à partir de la fin de l'en-tête, on peut le faire directement dans le fread ?

    Citation Envoyé par Matt_Houston Voir le message
    Tu peux remplacer toutes les occurrences de sizeof(char) par 1, c'est garanti.
    En fait je laisse sizeof(char) juste pour bien repérer dans mon code où il demande la taille des éléments quand j'arrangerais mon code je les ferais disparaître à la même occasion !

    Edit je viens de tester du coup medinoc avec ta fonction Arrondir4Sup() il me renvoie un nombre (précisément 786432 que j'envoie )
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sock_err = send(csock, bitmapImage_envoi,(entete.bpp/8)*entete.longueur*arrondi, 0);
    À la réception je récupère le même nombre d'informations mais rien ne change je n'ai toujours pas l'image complète :/

  10. #30
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Citation Envoyé par Blackbelt_29 Voir le message
    Pour le 510*511 c'est parce que j'avais testé sur une autre image (de taille 510*511) mais lors de mais teste pour Lena j'avais bien mis 512*512 !
    Ben alors mets-nous le code qui est en cause, pas une version d'il y a deux jours ! Sérieusement ça n'a pas de sens de raisonner sur des données qui ne sont pas exactement celles que tu as fournies à la machine avant de constater le comportement en question.


    Citation Envoyé par Blackbelt_29 Voir le message
    comment fait-on du coup pour lire à partir de la fin de l'en-tête, on peut le faire directement dans le fread ?
    La méthode propre est de ne pas fermer le fichier après avoir lu l'en-tête, auquel cas le curseur est déjà correctement positionné. Autrement il te faut l'avancer en utilisant fseek ou fread.

  11. #31
    Futur Membre du Club Avatar de Blackbelt_29
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2016
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2016
    Messages : 19
    Points : 9
    Points
    9
    Par défaut
    Je te rassure y a vraiment que le 510*110 qui a été rajouté après . En faut j'ai fait tous les tests, captures... et juste avant de poster sur le forum j'ai juste voulu vérifier avec une autre image mais tous les résultats viennent de l'image 512*512 et le code est exactement le même.

    Et du coup juste avant le fread je dois écrire : fseek(fichier, entete.taille_entete, SEEK_SET); ?
    Sinon je vais tester en ne pas fermant le fichier merci !

  12. #32
    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 519
    Points
    41 519
    Par défaut
    En fait, je me suis trompé sur ma formule: Au lieu de Arrondir4Sup(entete.largeur) * entete.hauteur * (entete.bpp/8), il faudrait plutôt utiliser ceci:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    Arrondir4Sup(entete.largeur * (entete.bpp/8)) * entete.hauteur
    (vu que c'est la taille en octets d'une ligne qui doit être arrondie aux 32 bits supérieurs, et non pas la taille en pixels)

    Et du coup juste avant le fread je dois écrire : fseek(fichier, entete.taille_entete, SEEK_SET); ?
    Plutôt offset que taille_entete, en fait.
    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.

  13. #33
    Membre expérimenté
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    Par défaut
    Bonsoir
    Il y a un truc que je ne comprends pas, pourquoi lire la taille du fichier dans le fichier ?
    Qu’est-ce qui justifie ce choix ?
    Et pourquoi ne pas faire simple ? C'est-à-dire l’envoi des données d’image ou fichier binaire en utilisant les sockets sans utiliser de structure ?.

    Essayez de procéder de manière simple avant de complexifier la chose. Tout d’abord, assurer-vous d’avoir la bonne taille du fichier non pas par lecture de l’en-tête, mais du flux grâce à ftell (offset fichier), ensuite avec la taille du fichier acquis, vous allez allouer de la mémoire pour la suite à savoir la lecture du fichier.

    Utiliser le buffer alloué pour lire le contenu du fichier et par la même occasion, vous allez écrire le contenu de celui-ci (buffer) sur la socket tout en s’assurant que l’on envoit bien les données (contrôle de lecture du fichier et contrôle d’écriture sur la socket).
    Le traitement fini, fermer le fichier, déconnecter le client et vider le buffer.

    Côté client:
    • Créez un fichier s’il n’existe pas, dans le cas contraire écrasez le fichier existant.
    • Allouez de la mémoire à un buffer. Cette mémoire doit être assez grande (vous pouvez faire autrement, c'est-à-dire envoyer la taille du fichier avant les données pour allouer la mémoire nécessaire) afin de recevoir les données.
      Dans mon exemple ci-dessous, la taille du buffer a été défini.
    • Pendant l’acquisition des données, procédez également à l’écriture du flux dans le fichier créé tout en contrôlant que la lecture et l'écriture ne soient pas erronées.
      Fin d’acquisition des données, fermez le fichier, se deconnecter du serveur et vider le buffer.


    Ce qui donne les codes sources ci-dessous: Attention, l’ensemble, les codes sources ci-dessous sont susceptibles de comporter des erreurs

    Code serveur
    Code C : 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
     
    /*
     ============================================================================
     Name        : Untitled 2.c
     Author      : SAMBIA39
     Version     : 0.1
     Copyright   : Copyright (c) 30/06/2016 SAMBIA39. All rights reserved.
     Description : Ansi-style
     ============================================================================
     */
     
    #define DEF_PORT    8888    //Port serveur par defaut
    #define DEF_CLTM    25      //Max client
     
    #include <errno.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
     
    #include <fcntl.h>
    #include <unistd.h>
    #include <sys/stat.h>
    #include <sys/wait.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
     
    /*
     *  Ensemble de routine 
     *  gestion des erreur
     */
    void f_print_error( char *pmsg ){
     
        extern int errno;
        extern const int sys_nerr;
        extern const char *const sys_errlist[];
     
        fprintf( stderr, "(%d)\t:%s\n", errno,
                (!pmsg) ? "inconnue" : pmsg );
        if( 0 < errno && errno < sys_nerr )
            fprintf( stderr, "info\t:%s\n",
                    sys_errlist[errno] );
    }
     
    int f_error( char *psmg ){
        f_print_error(psmg);
        return -1;
    }
     
    void f_fatal_error( char *pmsg ){
        f_print_error(pmsg);
        exit( EXIT_FAILURE );
    }
     
     
    /*
     *  Acquisition de la taille de fichier
     */
    long f_get_size_file(char *pfile_name){
     
        long l_size = 0;
        FILE *pFile = NULL;
        if( NULL== (pFile =fopen(pfile_name, "rb")) )
            return f_error("erreur open file");
        if( -1 == fseek(pFile, 0, SEEK_END) )
            return f_error("erreur seek");
        l_size = ftell(pFile);
        if( -1 == fclose(pFile) )
            return f_error("erreur close");
        return l_size;
    }
     
    /*
     *  Creation d'une socket
     */
    int f_get_socket( int iPort, int inb_clt ){
     
        int isock = -1;
        const int ioptSock;
        struct sockaddr_in addr_sock;
     
        if( -1 == (isock = socket(AF_INET, SOCK_STREAM, 0) ) )
            return f_error("Erreur socket");
        if( -1 == setsockopt(isock, SOL_SOCKET, SO_REUSEADDR,
                             &ioptSock, sizeof(int) ) ){
            close( isock );
            return f_error("Erreur set option socket" );
        }
     
        iPort = ( BUFSIZ > iPort ) ? DEF_PORT : iPort;
        memset((char*)&addr_sock, 0, sizeof(struct sockaddr_in) );
        addr_sock.sin_family = AF_INET;
        addr_sock.sin_port = htons(iPort);
        addr_sock.sin_addr.s_addr = htonl(INADDR_ANY);
     
        if( -1 == bind( isock, (struct sockaddr*)&addr_sock,
                       sizeof(struct sockaddr_in))){
            close( isock );
            return f_error("Erreur bind socket" );
        }
     
        inb_clt = ( !inb_clt ) ? DEF_CLTM : inb_clt;
        if( -1 == listen(isock, inb_clt) ){
            close( isock );
            return f_error("Erreur listen");
        }
        return isock;
    }
     
    /*
     *  Fonction qui ouvre le fichier
     */
    FILE *f_open_file( char *ptr ){
     
        FILE *pFile = NULL;
        if( NULL == (pFile = fopen(ptr, "rb"))){
            f_print_error("erreur open file");
            return NULL;
        }
        return pFile;
    }
     
    /*
     *  Fonction principal
     */
    int main( void ){
     
        int isock = -1;
        int offset = 0;
        char *buff = NULL;
        int isock_clt = -1;
        FILE *pFile = NULL;
        size_t size_file = 0;
        size_t size_file_send = 0;
        size_t size_file_read = 0;
     
        /*
         *  Création de la socket
         */
        if( -1 == (isock = f_get_socket(DEF_PORT, DEF_CLTM)))
            f_fatal_error("ERREUR FATAL CREAT SOCKET\n");
        fprintf( stdout, "SERVEUR START\n" );
     
        /*
         *  Attente d'une connection 
         */
        if( -1 == ( isock_clt = accept(isock, NULL, 0) ) ){
            close(isock);
            f_fatal_error("ERREUR FATAL ACCEPT SOCKET");
        }
        shutdown(isock, 2);
        close(isock);
     
        /*
         *  (1)Acquisition de la taile du fichier
         *  (2)Allocation du buffer fichier
         *  (3)Ouverture du fichier
         *  (4)Lecture du fichier
         *  (5)Envoie des data au client
         *  (6)Fermeture du fichier
         *  (7)Close connection socket et vidé buffer
         */
     
        //(1) & (2)
        size_file = f_get_size_file("image.jpg");
        if( NULL == ( buff = malloc( size_file *sizeof(char)) ))
            f_fatal_error("ERREUR ALLOCATION DATA");
        //(3)
        if( NULL == ( pFile = f_open_file("image.jpg")) )
            f_fatal_error("ERREUR OPEN/READ DATA\n");
     
     
        fprintf( stdout, "DATA SERVEUR SIZE\t:%d\n", (int)size_file );
        fprintf( stdout, "SERVEUR READ DATA FILE.....\n" );
     
        //(4) & (5)
        while( 0 < (size_file_read = fread(buff, sizeof(char),
                                           size_file, pFile))){
            if( -1 == (int)size_file_read )
                f_fatal_error("ERREUR READ DATA\n");
            while( 0 < (size_file_send = send(isock_clt, buff,
                                              size_file_read, 0)) ){
                offset += size_file_send;
                size_file_read -= size_file_send;
            }
        }
     
        //(6)
        if( -1 == fclose(pFile) ){
            shutdown(isock_clt, 2);
            free( buff );
            buff = NULL;
            f_fatal_error("ERREUR FATAL CLOSE DATA\n");
        }
        fprintf( stdout, "SERVEUR SEND DATA FILE OK..\n");
     
        //(7)
        shutdown(isock_clt, 2);
        close( isock_clt );
        free( buff );
        buff = NULL;
     
        return EXIT_SUCCESS;
    }

    Code client
    Code C : 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
     
    /*
     ============================================================================
     Name        : Untitled 1.c
     Author      : SAMBIA39
     Version     : 0.1
     Copyright   : Copyright (c) 30/06/2016 SAMBIA39. All rights reserved.
     Description : Ansi-style
     ============================================================================
     */
     
     
    #define DEF_PORT    8888    //port serveur
     
    #include <errno.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    #include <netdb.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <sys/stat.h>
    #include <sys/wait.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
     
    /*
     *  Ensemble de routine
     *  gestion des erreur
     */
    void f_print_error( char *pmsg ){
     
        extern int errno;
        extern const int sys_nerr;
        extern const char *const sys_errlist[];
     
        fprintf( stderr, "(%d)\t:%s\n", errno,
                (!pmsg) ? "inconnue" : pmsg );
        if( 0 < errno && errno < sys_nerr )
            fprintf( stderr, "info\t:%s\n",
                    sys_errlist[errno] );
    }
     
    int f_error( char *psmg ){
        f_print_error(psmg);
        return -1;
    }
     
    void f_fatal_error( char *pmsg ){
        f_print_error(pmsg);
        exit( EXIT_FAILURE );
    }
     
     
    /*
     *  Creation socket client
     */
    int f_get_socket_clt( char *pmsg, int iport ){
     
        int isock = -1;
        const int iopt = 1;
        struct hostent *phost;
        struct sockaddr_in sock;
     
        if( NULL == ( phost = gethostbyname(pmsg)) )
            return f_error("erreur addr serveur");
        if( -1 == ( isock = socket(AF_INET, SOCK_STREAM, 0)))
            return f_error("erreur socket");
        if( -1 == setsockopt(isock, SOL_SOCKET, SO_REUSEADDR, &iopt,
                             sizeof(int)) ){
            free( phost );
            phost = NULL;
            close(isock);
            return f_error("Erreur option socket");
        }
     
        iport = ( BUFSIZ > iport ) ? DEF_PORT : iport;
        sock.sin_family = phost->h_addrtype;
        sock.sin_port = htons(iport);
        memcpy((char*)&sock.sin_addr.s_addr, phost->h_addr,
               phost->h_length );
        if( -1 == connect(isock, (struct sockaddr*)&sock,
                          sizeof(struct sockaddr_in))){
            close(isock);
            free( phost );
            phost = NULL;
            return f_error("Erreur connection serveur");
        }
        return isock;
    }
     
    /*
     *  Fonction qui ouvre le fichier
     */
    FILE *f_open_file( char *ptr ){
     
        FILE *pFile = NULL;
        if( NULL == ( pFile = fopen(ptr, "w+"))){
            f_print_error("Erreur open file");
            return NULL;
        }
        return pFile;
    }
     
    /*
     *  Fonction principal
     */
    int main( void ){
     
        int isock = -1;
        char buff[BUFSIZ];
        FILE *pFile = NULL;
        size_t size_read = -1;
        size_t size_write = 0;
     
        memset( buff, 0, BUFSIZ );
     
        /*
         * Ouverture du fichier ( création )
         */
        if( NULL == (pFile = f_open_file("image.jpg")) )
            f_fatal_error("ERREUR FATAL CREATE FILE");
     
        /*
         *  Acquisition socket
         */
        if( -1 == ( isock = f_get_socket_clt("localhost", DEF_PORT) ) )
            f_fatal_error("ERREUR SOCKET");
     
        /*
         *  Reception des data serveur
         */
        fprintf( stdout, "READ DATA SERVEUR\n");
        while( 0 != (size_read = read( isock, buff, sizeof(buff)) ) ){
            if( -1 == (int)size_read )
                f_fatal_error("ERREUR LECTURE DATA");
     
            /*
             *  Ecriture des data dans le fichier
             *  crée
             */
            size_write = fwrite(buff, 1, sizeof(buff), pFile );
            if( -1 == (int)size_write )
                f_fatal_error("ERREUR WRITE DATA");
        }
     
        /*
         *  Close fichier fin d'ecriture
         */
        if( -1 == fclose(pFile) )
            f_fatal_error("ERREUR CLOSE FILE");
        fprintf( stdout, "DATA RECV OK\n" );
     
        /*
         *  Déconnection du client
         */
        shutdown(isock, 2);
        close( isock );
     
        // reset buffeur;
        memset( buff, 0, BUFSIZ );
     
        return EXIT_FAILURE;
    }

    Si vous comptez utiliser votre structure, pas besoin d’autant de membres. Personnellement, je considère que 5 membres c’est déjà trop, 4 c’est le max (s’il faut plus, je les regroupe dans une autre structure).
    Pour la structure, vous pouvez faire de la façon suivante exemple:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    /*
     *  Structure data
     *  ensemble des infos du
     *  fichier y compris sont 
     *  contennu
     */
    typedef struct s_data{
        size_t size_file;       //taille fichier
        char t_name[127];       //nom du fichier
        void *ptr_buffer;       //flux de donnée ( contenue future des datat);
    }FILE_DATA;

    En utilisant une structure avec un pointeur comme membre, il faut s’assurer d’envoyer les données les unes après les autres, à savoir le non du fichier puis la taille et au final les données pointées par le pointeur. Dans le cas contraire, si une taille fixe du buffer a été définie, vous pouvez envoyer le tout et faire le nécessaire dans la partie client.

    à bientôt
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

Discussions similaires

  1. Problème lors de l'envoi d'une newsletter
    Par ghir_ana dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 06/07/2011, 23h51
  2. [AJAX] Envoie d'une requête AJAX
    Par tidus_6_9_2 dans le forum AJAX
    Réponses: 16
    Dernier message: 14/04/2010, 15h23
  3. Envoi d'une matrice sur socket UDP
    Par caubios dans le forum Qt
    Réponses: 0
    Dernier message: 10/02/2010, 19h10
  4. Réponses: 4
    Dernier message: 04/02/2010, 14h44
  5. Réponses: 9
    Dernier message: 15/03/2007, 16h17

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