Partage
  • Partager sur Facebook
  • Partager sur Twitter

perror : bad address

Serveur/client udp recvfrom

Sujet résolu
    16 février 2022 à 10:41:04

    Bonjour,

    Voilà j'essaye de transmettre une information entre un client et un serveur en UDP (type de l'info tableau unsigned char de taille 5).

    Lorsque je lance mon serveur puis mon client, au niveau du recvfrom sur le serveur perror retounr bad address (-1) cependant par la suite je récupère quand même les données que j'ai transmis. Je ne comprend pas pourquoi j'ai cette erreur étant donnée que la transmission à bien lieu.

    Code srv :

    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <netdb.h>
    
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    #include <signal.h> 
    
    #include<pthread.h>
    #include <string.h>
    #define TAILLE_MAX 50
    
    
    int sockfd;
    
    int main()
    {
    	// Creating socket file descriptor
        if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0))<0)
        { //create socket serveur
            perror("socket creation failed");
            exit(EXIT_FAILURE);
        }
    
    	//configuration adresse du serveur
    	struct sockaddr_in servaddr,cliaddr; 
    	memset(&servaddr, 0, sizeof(servaddr));
        memset(&cliaddr, 0, sizeof(cliaddr));
           
        // Filling server information
        servaddr.sin_family = AF_INET; // IPv4
        servaddr.sin_port = htons(50000);
        servaddr.sin_addr.s_addr = inet_addr("192.168.10.203"); // on peut remplacer inet_pton(AF_INET,"127.0.0.1",&(serveur_addr.sin_addr));
    
    	//on appaire le socket au reseau
        if (bind(sockfd,(const struct sockaddr *)&servaddr,sizeof(servaddr))<0) // bind(sockfd,(struct sockaddr*)&servaddr,sizeof(struct sockaddr));
        {
            perror("bind failed");
            exit(EXIT_FAILURE);
        }
    	else printf("bind success: %d\n",sockfd);
        //int end=0;
        //char gestion [TAILLE_MAX][500]; // taille en longueur variable
        unsigned char info_length[5]; // recevoir l'information
        unsigned long int p = sizeof(cliaddr);
        socklen_t *len =(socklen_t *)p; 
    	//while(end==0) //boucle infini qui attend de recevoir qq chose si on veut tuer proprement le serveur end=1
    	//{ 
    		if(recvfrom(sockfd, info_length, sizeof(info_length),MSG_WAITALL, ( struct sockaddr *) &cliaddr,len)<1) // bloquant
    			perror("recvfrom failed ");
            for(int i=0;i<5;i++)
                printf("rang %d data1 %02x \n",i,info_length[i]);
    
    	//}
        close(sockfd);
        printf("close \n");
    
        //pthread_exit(NULL);
        return 0;
    }
    

    client :

    // Client side implementation of UDP client-server model
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <netinet/in.h>
    #include <time.h>
    #include <iostream>
    //#include <raspicam/raspicam_cv.h>
    #include <opencv2/imgcodecs.hpp>
    #include <opencv2/opencv.hpp>
    #include <netdb.h>
    #include <vector>
    #include <opencv2/core/core.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    #include <opencv2/videoio/videoio.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #define TAILLE_PACK 10000
    
    //g++ -Wall -o cli_dvp cli_dvp.cpp -lopencv_core -lopencv_highgui -lopencv_videoio -lopencv_imgcodecs
    // camera_csi
    //g++ -Wall -o camera_csi camera_csi.cpp -I/usr/local/include/ -lraspicam -lraspicam_cv -lmmal -lmmal_core -lmmal_util -lopencv_core -lopencv_highgui -lopencv_videoio -lopencv_imgcodecs 
    
    using namespace cv;
    using namespace std; 
    
    //int verif_srv_reply(char server_reply[],int message_index, char message[]);
    //int verif_send (int sent);
    //int verif_recv (int recv);
    
    //variable globale
    pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
    pthread_cond_t  cond_var = PTHREAD_COND_INITIALIZER;
    
    // Driver code
    int main() {
    	clock_t ti,tf,ti2,tf2; //possibiliter de calculer temps d'envoie
    	unsigned long t_tot,t_tot2;
    	ti = clock();
    	unsigned char id=1;
    	int sockfd; // socket client
    	Mat img;
    	img = imread("3.jpg", IMREAD_COLOR);	
    
    	// Creating socket file descriptor
    	if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) { // create the socket SOCK_DGRAM = UDP Protocol
    		perror("socket creation failed"); // AF_INET = IPV4
    	exit(EXIT_FAILURE);// Test to know if it work
    	}
    		
    	//Configuration server informatio
    	struct sockaddr_in servaddr;
    	memset(&servaddr, 0, sizeof(servaddr));
    	servaddr.sin_family = AF_INET; //Ipv4
    	servaddr.sin_port = htons(50000);//port sur lequel on parle
    	servaddr.sin_addr.s_addr = inet_addr("192.168.10.203"); // @ip du serveur (on peut faire en local 127.0.0.1)
    
    	//envoie d'une image
    	uchar * arr = img.isContinuous()? img.data: img.clone().data;
    	uint length = img.total()*img.channels(); //int32
    	printf("length %d , hexa %08x \n",length,length);
    	unsigned char data1[5];
    	data1[0]=id;
    	unsigned char cpt = 24;
    	for(int i=1;i<5;i++)
    	{
    		data1[i]=length>>cpt;
    		cpt-=8;
    		printf("rang %d, data %02x\n",i,data1[i]); // data1 = []
    	}
    	//envoie de la taille de l'image + id 
    	printf("Envoie ! \n");
    	
    	if(sendto(sockfd, data1,sizeof(data1),MSG_CONFIRM, (struct sockaddr *) &servaddr,sizeof(servaddr))<0) //MSG_CONFIRM / MSG_WAITILL
    		perror("Client ");
    
    	close(sockfd);
    	printf("Close ! \n");
    	return 0;
    }

    J'envoie le tableau suivant [01,00,0f,d2,00], voici ce que je récupère dans ma console :

    bind success: 3
    recvfrom failed : Bad address
    type error -1
    rang 0 data1 01
    rang 1 data1 00
    rang 2 data1 0f
    rang 3 data1 d2
    rang 4 data1 00
    close

    Merci de votre aide :)


    • Partager sur Facebook
    • Partager sur Twitter
      16 février 2022 à 19:28:55

      Tu as posté trois messages sur le sujet et tu n'as reçu  aucune réponse utile.
      Tu en avait posté deux dans la catégorie C++ alors qu'il était évident que c'est du C.
      Tu es, me semble-t-il, sur Linux. J'ai essayé de compiler sur Windows et j'ai des erreurs.
      D'abord essaies de compiler avec les options -Wall et -Wextra pour voir les Warning éventuels.
      Ensuite, il y a une variable appelée errno associée à perror(). Tu pourrais la tester et/ou l'afficher avant et après chaque appel "douteux".
      Ou bien, tu la mets à 0 avant chaque appel.
      Je n'ai jamais utilisé le protocole UDP, seulement TCP.
      Je ne me rappelle pas non plus si le send() fait un flush du buffer. C'est peut-être une piste à essayer.
      • Partager sur Facebook
      • Partager sur Twitter

      Le Tout est souvent plus grand que la somme de ses parties.

        17 février 2022 à 11:01:35

        Oui j'ai posté en c++ parce que derrière j'utilise du c++ (et donc je compile toujours avec g++) juste pas affiché sur les forums du coup j'avais oublié que à la base le serveur est en C.

        De plus je compile déjà avec Wall, et j'ai essayé avec Wextra à l'instant mais je n'ai pas d'erreur de compilation. Je vais me penché sur cette histoire d'erno. Et pour les autres sujets, je me suis vite rendu compte que la manière de réfléchir et gérer plusieurs clients en udp était complètement différente du coup finalement ils ne servent à rien mais je ne sais pas comment les supprimer :euh:

        • Partager sur Facebook
        • Partager sur Twitter
          17 février 2022 à 11:23:31

          Je viens de regarder le code de ton serveur :

              unsigned long int p = sizeof(cliaddr);
              unsigned long int *len =(unsigned long int *)p;

          C'est quoi que cet alambique ?

          Tu affectes la taille de la structure à un pointeur ? Et il va pointer où après le pointeur ? C'est plutôt l'adresse de la variable qu'il lui faut pas sa valeur ! 

          Et puis envois directement l'adresse de p à recvfrom ça sera plus simple !

          -
          Edité par rouIoude 17 février 2022 à 12:35:09

          • Partager sur Facebook
          • Partager sur Twitter
          ...

          perror : bad address

          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
          • Editeur
          • Markdown