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 :

Envoie de struct dans une socket impossible !


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti Avatar de beau_g
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2017
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Nièvre (Bourgogne)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2017
    Messages : 26
    Par défaut Envoie de struct dans une socket impossible !
    Bonjour à tous,

    Dans le cadre d'un projet je dois envoyé, via une socket, un "protocol request packet" en multicast à différent système, afin de pouvoir récupérer certaines informations de ces systèmes.
    En simulant sur l'ordinateur: j'ai réussi tt d'abord à envoyer des simples char comme "hello, world" en multicast vers un "client", mais je n'arrive pas à envoyer des information plus complexe en struct, je vous montre mon programme:

    Voici tt d'abord le main principal:

    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
    /*
     * workstation.c
     *
     *  Created on: 3 août 2017
     *      Author: Aymeric
     */
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <string.h>
    #include <pthread.h>
    #include "unicastSocketRcvfrom.h"
    #include "multiSocketSendto.h"
    #include "request.h"
     
    #define PORT1 12345
    #define PORT2 7
     
    #define GROUP_IP "225.0.0.37"
    #define ADDRIP "127.0.0.1"
     
     
    /*Returns 0 if OK, a negative value if EOF.*/
     
    scanf("\n\n%s", &request[2]);
     
    	return request[2];
     
    }*/
     
    int fpurge(FILE *f)
    {
    	int c;
    	while((c=fgetc(f))!=EOF && c!='\n')
    	{ }
    	return (c==EOF ? -1 : 0);
    }
     
     
    void *send_multi(void *arg){
     
    	struct IPRequest *rq = {0};
     
    	rq->unicast_ip=10000010;
    	rq->unicast_port = 7;
    	rq->protocol_identifier=00;
     
    	while(1)
    	{
    		printf("Push a letter S or Q:\r\n");
    		char c = getchar();
    		fpurge(stdin);
     
    		if ((c=='s')||(c=='S'))
    		{
    			multiSocketSend(PORT1, GROUP_IP, rq);
    		}
    		else if ((c=='q')||(c=='Q'))
    		{
    			printf("QUIT");
    			break;
    		}
    		else
    		{
    			printf("Invalid key, tape 'S' to send a message, 'Q' to exit.");
    		}
     
    	}
    	pthread_exit(NULL); /* Fin du thread */
    	return NULL;
     
    }
     
     
    int main(void)
    {
     
    	/* this variable is our reference to the second thread */
    	pthread_t threadSendmulti;
     
     
    	/* create a second thread which executes send_uni(void *arg) */
     
    	if(pthread_create(&threadSendmulti, NULL, send_multi, NULL))
    	{
    		fprintf(stderr, "Error creating threadSendmulti\n");
    		return 1;
    	}
     
    	/* wait for the second thread to finish */
    	if(pthread_join(threadSendmulti, NULL))
    	{
    		fprintf(stderr, "Error joining threadSendmulti\n");
    		return 2;
    	}
    	return 0;
    }
    La fonction multiSocketSendto();

    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 "multiSocketSendto.h"
     
    int multiSocketSend (int PORT,char *GROUP_IP, struct IPRequest *request){
    	struct sockaddr_in addr;
    	int msock;
    	WSADATA WSAData;                  // Contains details of the Winsock implementation
     
     
    	// Initialize Winsock.
    	if (WSAStartup (MAKEWORD(1,1), &WSAData) != 0)
    	{
    		printf("Error n°%d : Error during initialization.\n", SOCKET_ERRNO);
    	    //exit(SOCKET_ERRNO);
    		return SOCKET_ERRNO;
    	}
     
    	//create what looks like an ordinary UDP socket
    	if ((msock=socket(AF_INET,SOCK_DGRAM,0)) < 0)
    	{
    		printf("Error n%d : Unable to initialize socket.\n",SOCKET_ERRNO);
    		//exit(SOCKET_ERRNO);
    		return SOCKET_ERRNO;
    	}
     
    	//set up destination address
    	memset(&addr,0,sizeof(addr));
    	addr.sin_family=AF_INET;
    	addr.sin_addr.s_addr=inet_addr(GROUP_IP);
    	addr.sin_port=htons(PORT);
     
    	//now just sendto() our destination!
     
    	if (sendto(msock,&request,sizeof(struct IPRequest),0,(struct sockaddr *) &addr,
    			sizeof(addr)) < 0)
    	{
    		printf("Error n%d : Unable to send message.\n",SOCKET_ERRNO);
    		//exit(SOCKET_ERRNO);
    		return SOCKET_ERRNO;
    	}
     
    	printf("Sending successfully!\n");
     
    	WSACleanup();
    	return 0;
     }

    et le header de la requete (request.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
     
    #ifndef REQUEST_H_
    #define REQUEST_H_
     
     
    #include <stdint.h>
     
     
    typedef uint8_t u_int8_t;
    typedef uint16_t u_int16_t;
    typedef uint32_t u_int32_t;
     
     
    struct IPRequest
    {
        uint32_t  unicast_ip;
        uint8_t unicast_port;
        uint8_t protocol_identifier;
    };
     
     
    #endif /* REQUEST_H_ */

    A première vue mon programme ne présente pas d'erreur mais lorsque je lance le .exe du Debug, celui ci ne répond plus....

    Merci d'avance pour votre aide;

    bonne soirée !

    beaug

  2. #2
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Il faut clarifier ce qu'est un pointeur.

    Un pointeur ne doit pas être déréférencé s'il ne pointe pas sur une zone valide.
    Ligne 42 de principal, le pointeur est nul. Ligne suivante, on le déréférence pour y mettre des données!

    Un pointeur c'est fait pour désigner une donnée. Ici ligne 42 il faut créer une structure, pas un pointeur. Ligne 56 on passera à la fonction l'adresse de cette structure qui recevra ainsi un pointeur.

    Dans multiSocketSend ligne 33, la fonction attend l'adresse du buffer à transmettre. Il ne faut pas lui passer &request qui est l'adresse du pointeur (donc un struct IPRequest**), mais plutôt passer request qui est l'adresse des données.

  3. #3
    Membre averti Avatar de beau_g
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2017
    Messages
    26
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Nièvre (Bourgogne)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2017
    Messages : 26
    Par défaut
    Hello,

    merci pour ton aide, voici mes modifications, mais malheureusement ça ne marche tjrs pas, ça envoie mtn mais le message reçu est du genre "--|#{|"

    multiSocketSendto.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 "multiSocketSendto.h"
     
    int multiSocketSend (int PORT,char *GROUP_IP, struct test *request){
     
    	struct sockaddr_in addr;
    	int msock;
    	WSADATA WSAData;                  // Contains details of the Winsock implementation
     
     
    	// Initialize Winsock.
    	if (WSAStartup (MAKEWORD(1,1), &WSAData) != 0)
    	{
    		printf("Error n°%d : Error during initialization.\n", SOCKET_ERRNO);
    	    //exit(SOCKET_ERRNO);
    		return SOCKET_ERRNO;
    	}
     
    	//create what looks like an ordinary UDP socket
    	if ((msock=socket(AF_INET,SOCK_DGRAM,0)) < 0)
    	{
    		printf("Error n%d : Unable to initialize socket.\n",SOCKET_ERRNO);
    		//exit(SOCKET_ERRNO);
    		return SOCKET_ERRNO;
    	}
     
    	//set up destination address
    	memset(&addr,0,sizeof(addr));
    	addr.sin_family=AF_INET;
    	addr.sin_addr.s_addr=inet_addr(GROUP_IP);
    	addr.sin_port=htons(PORT);
     
    	//now just sendto() our destination!
     
    	if (sendto(msock,request,sizeof(request),0,(struct sockaddr *) &addr,  //strlen+1
    			sizeof(addr)) < 0)
    	{
    		printf("Error n%d : Unable to send message.\n",SOCKET_ERRNO);
    		//exit(SOCKET_ERRNO);
    		return SOCKET_ERRNO;
    	}
     
    	printf("Sending successfully!\n");
     
    	WSACleanup();
    	return 0;
     }
    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
    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
     
    void *send_multi(void *arg){
    /*
    	char *rq;
    	rq = request_app();
    */
        struct test rq;
     
    	rq.test1 ="000";
    	rq.test2 ="001";
    	rq.test3 ="002";
     
    	while(1)
    	{
    		printf("Push 's' to send the protocol, or 'q' to exit:\r\n");
    		char c = getchar();
    		fpurge(stdin);
     
    		if ((c=='s')||(c=='S'))
    		{
    			multiSocketSend (PORT1, GROUP_IP, &rq);
     
    		}
    		else if ((c=='q')||(c=='Q'))
    		{
    			printf("QUIT");
    			break;
    		}
    		else
    		{
    			printf("Invalid key, tape 'S' to send the protocol, 'Q' to exit.");
    		}
     
    	}
    	pthread_exit(NULL); //Fin du thread
    	return NULL;
     
    }
     
    void *rcv_uni(void *arg)
    {
     
    	while (1)
    	{
     
    		unicastSocketRvcfrom(PORT2,ADDRIP);
     
    	}
    	return NULL;
    }
     
    int main(void)
    {
     
    	//this variable is our reference to the second thread
    	pthread_t threadSendmulti;
     
     
    	//create a second thread which executes send_uni(void *arg)
     
    	if(pthread_create(&threadSendmulti, NULL, send_multi, NULL))
    	{
    		fprintf(stderr, "Error creating threadSendmulti\n");
    		return 1;
    	}
     
    	// wait for the second thread to finish
    	if(pthread_join(threadSendmulti, NULL))
    	{
    		fprintf(stderr, "Error joining threadSendmulti\n");
    		return 2;
    	}
     
     
    	return 0;
     
    }
    Nom : Captured.PNG
Affichages : 86
Taille : 1,0 Ko

  4. #4
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Ligne 34, la taille à transmettre qui était bonne est devenue fausse. Il ne faut pas sizeof(request) mais sizeof(*request) ou sizeof(struct test).
    D'autre part j'espère que la struct test ne contient que des choses transmissibles en particulier qu'elle ne contient aucun pointeur. En aucun cas un pointeur n'a de sens en dehors de l'application. D'autant que tes commentaires parlent de chaînes transmises et ton code transmet une structure!
    Pense bien à activer tous les warnings de compilation. Et n'oublie pas qu'un warning c'est une erreur.

Discussions similaires

  1. [PHP 5.2] Envoi de données en XML dans une socket
    Par saturnino dans le forum Langage
    Réponses: 2
    Dernier message: 10/09/2009, 10h03
  2. [MySQL] Envoi d'information dans une base de donnée via formulaire
    Par Mysti¢ dans le forum PHP & Base de données
    Réponses: 7
    Dernier message: 30/03/2006, 20h35
  3. [VB.NET] Envoyer TreeNodes dans une socket
    Par Aspic dans le forum VB.NET
    Réponses: 10
    Dernier message: 18/02/2006, 16h29
  4. Réponses: 20
    Dernier message: 23/09/2005, 13h50
  5. write() dans une socket.. unix
    Par slack dans le forum Réseau
    Réponses: 5
    Dernier message: 18/12/2002, 20h42

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