Partage
  • Partager sur Facebook
  • Partager sur Twitter

Serveur udp multithreading

pthread_create retourne pas d'erreur mais ne se lance jamais

    5 mai 2022 à 15:20:04

    Bonjour à tous,

    Je suis en train de coder un serveur udp en multithreading qui a pour but de recevoir des morceaux d'images de les stocker dans un tableau et lorsque ce tableau à l'ensemble des données décrivant l'image, on lance un thread de reconstruction (utilisation opencv).

    Voici le code du serveur :

    // server program for udp connection
    #include <stdio.h>
    #include <strings.h>
    #include <sys/types.h>
    #include <arpa/inet.h>
    #include <sys/socket.h>
    #include<netinet/in.h>
    #define PORT 5000 // c'est le port 300000 qui ne marche pas en udp
    #define MAXLINE 1000
    
    //lisa 
    #include <signal.h>
    #include <pthread.h>
    #include <sys/time.h>
    #include <time.h>
    #include <math.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <netdb.h>
    #include <iostream>
    #include <opencv2/core/core.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    #include <opencv2/videoio/videoio.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/imgcodecs/imgcodecs.hpp>
    #define TAILLE_PACK 10000
    #define N 4 // entête
    #define CLI_MAX 50
    #define varia 8
    #define BUFFER_SIZE 50
    #define T_max 5
    
    //g++ -Wall -o srv udp_srv.cpp -lopencv_core -lopencv_highgui -lopencv_imgcodecs -lpthread
    
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 
    pthread_cond_t  cond_var = PTHREAD_COND_INITIALIZER;
    
    void* server(void* data1);
    
    typedef struct
    {
        int index;
        int longueur;
        int client;
        int cpt;
        int *tab;
        int cpt1;
        int *tab_launch;
        int *reponse;
        int *thread_check;
    }Donnee;
    
    
    int img_ino[CLI_MAX][100000]; //plus tard pr alloc dynamique //segmentation fault à cause taille 
    // Driver code
    int main()
    {
        clock_t time1[CLI_MAX]={0};
        for (int i = 0;i<CLI_MAX;i++)
            time1[i]=0;
        struct timeval timeout={0,500}; //set timeout for 2 seconds
    
    	int info[N+TAILLE_PACK];
    	int tab[CLI_MAX][4];
        int raz[CLI_MAX]={0};
        int thread_cli[T_max]={0};
        
    	for(int i=0;i<CLI_MAX;i++) //init à une valeur diff de 0 mais innategnable
    		tab[i][1]=100;
    	short int cpt_img_f[CLI_MAX]={0};
    	int verif[CLI_MAX][100];
        for(int i = 0;i<CLI_MAX;i++)
            for (int j=0;j<100;j++)
                verif[i][j]=0;
        struct timespec now1,now2,now3,now4,now5,now6,now7,now8,now9,now10,now11,now12,now13,now14;
        char strNow[ BUFFER_SIZE ];
    
    	int listenfd;
    	struct sockaddr_in servaddr, cliaddr;
    	bzero(&servaddr, sizeof(servaddr));
    
    	// Create a UDP Socket
    	listenfd = socket(AF_INET, SOCK_DGRAM, 0);		
    	servaddr.sin_addr.s_addr = htonl(INADDR_ANY); //inet_addr("192.168.10.203");
    	servaddr.sin_port = htons(PORT);
    	servaddr.sin_family = AF_INET;
    
    
    	// bind server address to socket descriptor
    	bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr));
        //setsockopt(listenfd,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(struct timeval));
    	
    	//receive the datagram
    	socklen_t len;
    	len = sizeof(cliaddr); //len is value/result
    
    
    	int length=0;
    	int message_index = 0;
    	int r ;
        int message;
    	int nb_msg ;
    	int end = 0;
        int n;
        unsigned long compteur_thread[T_max]={0};
        struct sockaddr_in tab_addr[CLI_MAX];
        
    	clock_t ti,tf; //possibiliter de calculer temps d'envoie
    
        Donnee p;
        p.tab = (int*)malloc(T_max*sizeof(int)); // on alloue de la mémoire pour tab
        p.cpt = 0;
        p.thread_check = (int*)malloc(T_max*sizeof(int));
        p.tab_launch = (int*)malloc(CLI_MAX*sizeof(int)); // on alloue de la mémoire pour tab
        p.reponse = (int*)malloc(CLI_MAX*sizeof(int));
        for(int h=0;h<CLI_MAX;h++)
        {
           p.tab_launch[h]=1;
           p.reponse[h]=0;
        }
    
        int *return_value;
    
        //on initialise les variables à 0
        p.tab[0] = 0;
        p.tab[1] = 0;
        p.tab[2] = 0;
        p.tab[3] = 0;
        p.tab[4] = 0;
        p.thread_check[0] = 0;
        p.thread_check[1] = 0;
        p.thread_check[2] = 0;
        p.thread_check[3] = 0;
        p.thread_check[4] = 0;
        p.cpt1=0;
        p.index=0;
        pthread_t threads[T_max];
    	while(end == 0)
    	{
            tf = clock();
            
    		n = recvfrom(listenfd, (int*)info, (N+TAILLE_PACK)*sizeof(int),MSG_WAITALL, (struct sockaddr*)&cliaddr,&len); //receive message from server
            timeout={0,500}; // quand 2 clients arrivent successivement
            setsockopt(listenfd,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(struct timeval)); // recvfrom non bloquant après 2 secondes
            //printf("n %d\n",n);
            if(n>=0) // i reçoit une data il l'a traite
            {
                ti = clock();
                time1[info[0]]=ti; //heure du dernier msg reçu par client
                //printf("msg received cleint %d temps %ld \n",info[0],time[info[0]]);
                 
                if(info[1]==0) //CAS RECEP LENGTH
                {
                    //on recup la length
                    length = info[3];
                    //printf("\n length %d\n",length);
                    tab[info[0]][0]=length;
                    tab_addr[info[0]]=cliaddr;
                    r = length % TAILLE_PACK;
                    tab[info[0]][2]=r;
                    nb_msg = ((length-r)/TAILLE_PACK)+1; // surement +1 pour le reste
                    tab[info[0]][1]=nb_msg;
                    //printf("Calcul iteration client %d\n",nb_msg);
                    //on dit merci au client d'avoir envoyer sa trame de début
                    message = 300;
                    int t = sendto(listenfd, &message, sizeof(int), 0,(struct sockaddr*)&cliaddr, sizeof(cliaddr));
    
                    //printf("Ma structure : \n- AF_INET %lu \n- port %lu\n- struct in_addr %lu\n- sin_zero %s\n- in_addr %lu\n",cliaddr.sin_family,cliaddr.sin_port,cliaddr.sin_addr,cliaddr.sin_zero,cliaddr.sin_addr.s_addr);
                   // printf("adresse de début du tableau %d\ncliaddr %d tab_addr[i] %d\n",tab_addr,cliaddr,tab_addr[info[0]]);
                   // printf("Structure en param de tab_addr :\n- AF_INET %lu \n- port %lu\n- struct in_addr %lu\n- sin_zero %s\n- in_addr %lu\n",tab_addr[info[0]].sin_family,tab_addr[info[0]].sin_port,tab_addr[info[0]].sin_addr,tab_addr[info[0]].sin_zero,tab_addr[info[0]].sin_addr.s_addr);
                    timespec_get( &now1, TIME_UTC );
                    strftime( strNow, BUFFER_SIZE, "%D %T", gmtime( &now1.tv_sec ) );
                    printf("%s.%09ld msg 1 : ON A RECU TRAME DE START \n",strNow,now1.tv_nsec);
                    printf("\n\n\n\n");
                }
    
                if((info[1]==1)&& (tab[info[0]][1]!=100)) //CAS RECEP DATA et pas msg de fin filtre les trames qui s'incruste
                { 
                    timespec_get( &now2, TIME_UTC );
                    strftime( strNow, BUFFER_SIZE, "%D %T", gmtime( &now2.tv_sec ) );
                    printf("%s.%09ld msg 2 : index %d client %d\n",strNow,now2.tv_nsec,info[3],info[0]);
                    message_index = info[3];
                    if(message_index == nb_msg-1) // si on reçoit le reste
                    {
                        memcpy(&img_ino[info[0]][message_index*TAILLE_PACK],&info[4],(tab[info[0]][2])*sizeof(int)); // on stock dans tableau le reste et pas l'ensemble des data inutiles
                        /*for (int jean = 4;jean <tab[info[0]][2]+4;jean++)
                            printf("%d ",info[jean]);
                        printf("après le memcpy \n");
                        for(int elisa = 0;elisa<tab[info[0]][2];elisa++)
                        printf("%d ",img_ino[info[0]][info[3]*TAILLE_PACK+elisa]);*/
                    }
                    else
                    {
                        memcpy(&img_ino[info[0]][message_index*TAILLE_PACK],&info[4],TAILLE_PACK*sizeof(int)); // on stock ds tableau la data de 10 000
                        /*for (int jeanne = 4;jeanne <TAILLE_PACK+4;jeanne++)
                            printf("%d ",info[jeanne]);
                        printf("après le memcpy \n");
                        for(int marie = 0; marie <TAILLE_PACK;marie++)
                            printf("%d ",img_ino[info[0]][info[3]*TAILLE_PACK+marie]);*/
                    }
                    if ((verif[info[0]][message_index]==0)) // si c'est la 1er fois qu'on recoit cet index et qu'on a bien reçu la length au préalable
                        cpt_img_f[info[0]]+=1; // on incrémente le compteur d'image // le but est d'éliminer les trames parasites
                    verif[info[0]][message_index]=1; // on stock les index reçu
    
                }
            }
            /*for(int b=0;b<T_max;b++)
            {
                printf("le thread %d est dans l'état %d\n",p.index,threads[p.index].std::thread::joinable());
            }*/
            
           // printf("avant boucle for tab[i][1] %d client courant %d \n",tab[info[0]][1],info[0]);
            timespec_get( &now3, TIME_UTC );
            strftime( strNow, BUFFER_SIZE, "%D %T", gmtime( &now3.tv_sec ) );
            printf("%s.%09ld msg 3 : CLI 3 raz %d cpt_img_f %d \n",strNow,now3.tv_nsec,raz[3],cpt_img_f[3]);
            timespec_get( &now4, TIME_UTC );
            strftime( strNow, BUFFER_SIZE, "%D %T", gmtime( &now4.tv_sec ) );
            printf("%s.%09ld msg 4 : CLI 2 raz %d cpt_img_f %d \n",strNow,now4.tv_nsec,raz[2],cpt_img_f[2]);
            for(int i = 0;i<CLI_MAX;i++)
            {
                if((raz[i]!=1)&&(cpt_img_f[i]>0)) // si le client n'est pas encore éteint && qu'il a reçu au - 1 trame
                {
                    //time_t now2 = time(&now2);   
                    //printf("%ldh%ldm%lds cpt %d et tab %d client %d\n", (now2 / 3600) % 24, (now2 / 60) % 60, now2 % 60,cpt_img_f[i],tab[i][1],i);
                    if(cpt_img_f[i]==tab[i][1]) // si j'ai toutes les trames (cpt full img s'incrémente uniquement si il reçoit une trame différentes de la précédente)
                    { 
                        timespec_get( &now5, TIME_UTC );
                        strftime( strNow, BUFFER_SIZE, "%D %T", gmtime( &now5.tv_sec ) );
                        printf("%s.%09ld msg 5 : Reconstruction classique \n",strNow,now5.tv_nsec);
                         message = 100;
                        struct sockaddr_in var;
                        var = tab_addr[i];
                        int a = sendto(listenfd, &message, sizeof(int), 0,(struct sockaddr*)&var, sizeof(var)); // on envoie un message de fin pour dire au client qu'il peut se deco
                        time_t now4 = time(&now4);   
                        //printf("%ldh%ldm%lds message envoyer au client %d valid ou non %d \n", (now4 / 3600) % 24, (now4 / 60) % 60, now4 % 60,i,a);
                        
                            for(int i=0;i<T_max;i++)
                            {
                                if(p.tab[i]==0)
                                {
                                    p.cpt1++;
                                    p.index=i;
                                    //printf("index choisi %d\n",p.index);
                                    p.tab[i]=1;
                                    break;
                                }  
                            }
                        //RAZ 
                            cpt_img_f[i]=0; // ici très important pour ne pas reconstruire l'image 2 fois au prochain tour de boucle 
                            raz[i]=1;
                    
                        // data à faire passer en paramètre du thread
                            p.client = i;
                            p.longueur = tab[i][0];
                            p.cpt++;
                          
                            p.thread_check[p.index]=i; //tres important de le faire avant
                            int k = pthread_create(&threads[p.index], NULL, server, (void*) &p);
                            if(k != 0)
                                printf("error in creation of the thread %d error %d \n",p.index,k); 
                            timespec_get( &now6, TIME_UTC );
                            strftime( strNow, BUFFER_SIZE, "%D %T", gmtime( &now6.tv_sec ) );
                            printf("%s.%09ld msg 6 : le client %d a lancer le thread %d \n",strNow,now6.tv_nsec,i,p.index);
                            int j = pthread_detach(threads[p.index]);
                            if(j!=0)
                                printf("error dans le detachement du thread %d error %d\n",p.index,j);
                           
                                      
                    }   
                    
                    if((tf-time1[i])>0) // si ça fait un petit bout de temps que le client n'a pas parler 
                    { // 500 à voir comment on le règle  
                        timespec_get( &now7, TIME_UTC );
                        strftime( strNow, BUFFER_SIZE, "%D %T", gmtime( &now7.tv_sec ) );
                        printf("%s.%09ld msg 7 : ON REGARDE CLI QUI N'ONT PAS PARLER DEPUIS LONGTEMPS\n",strNow,now7.tv_nsec);
                        timespec_get( &now8, TIME_UTC );
                        strftime( strNow, BUFFER_SIZE, "%D %T", gmtime( &now8.tv_sec ) );
                        printf("%s.%09ld msg 8 : tf %d; ti %d; diff %d\n",strNow,now8.tv_nsec,tf,time1[i],tf-time1[i]);
                        timespec_get( &now9, TIME_UTC );
                        strftime( strNow, BUFFER_SIZE, "%D %T", gmtime( &now9.tv_sec ) );
                        printf("%s.%09ld msg 9 : cpt %d tab %d cli %d \n",strNow,now9.tv_nsec,cpt_img_f[i],tab[i][1],i);
                        if(cpt_img_f[i]!=tab[i][1]) // si il manque 1 trame ou +
                        {
                            for(int j = 0;j<tab[i][1];j++)
                            {
                                if(n==-1)
                                {
                                    timespec_get( &now10, TIME_UTC );
                                    strftime( strNow, BUFFER_SIZE, "%D %T", gmtime( &now10.tv_sec ) );
                                    printf("%s.%09ld msg 10 : verif cli %d rang %d etat %d\n",strNow,now10.tv_nsec,i,j,verif[i][j]);
                                }
                                if(verif[i][j]!=1) // on cherche les trames manquantes
                                { 
                                    timespec_get( &now11, TIME_UTC );
                                    strftime( strNow, BUFFER_SIZE, "%D %T", gmtime( &now11.tv_sec ) );
                                    printf("%s.%09ld msg 11 : missing trame %d client %d \n",strNow,now11.tv_nsec,j,i);
                                    message = j;
                                    struct sockaddr_in var1;
                                    var1 = tab_addr[i];
                                    sendto(listenfd, &message, sizeof(int), 0,(struct sockaddr*)&var1, sizeof(var1)); //on réclame
                                }
                            }
                        }
               
                    
                    }
              
                }
                if((raz[i]==1) && (p.tab_launch[i]==0)) // si le client est mort et que le thread de reconstruction s'est lancé
                { // manque la 
                    //RAZ pour ce client car il ne répondra plus de toute façon
                    time1[i]=0;
                    raz[i]=0;
                    //tab_addr[i]=0; // a voir plus tard
                    tab[i][1]=100;
                    cpt_img_f[i]=0;
                    p.tab_launch[i]=1; // contre  error: (-215:Assertion failed) !_img.empty() in function 'imwrite'
                    for (int j=0;j<100;j++)
                        verif[i][j]=0;
                    timespec_get( &now12, TIME_UTC );
                    strftime( strNow, BUFFER_SIZE, "%D %T", gmtime( &now12.tv_sec ) );
                    printf("%s.%09ld msg 14 : RAZ client %d \n",strNow,now12.tv_nsec,i);
                     struct sockaddr_in var;
                    var = tab_addr[i];
                    int message = 1000; 
                    sendto(listenfd, &message, sizeof(int), 0,(struct sockaddr*)&var, sizeof(var)); // on dis au client d'afficher rep et de mourir
                    timespec_get( &now13, TIME_UTC );
                    strftime( strNow, BUFFER_SIZE, "%D %T", gmtime( &now13.tv_sec ) );
                    printf("%s.%09ld msg 15 : on a retourner la reponse finale %d au client %d \n",strNow,now13.tv_nsec,message,i);
                }  
            }
        }  
    	close(listenfd);
    	return 0;
    }
    
    
    void* server(void* data1)
    {
        struct timespec now1,now2,now3,now4,now5;
        char strNow[ BUFFER_SIZE ];
        //recopiage de donnée
        timespec_get( &now1, TIME_UTC );
        strftime( strNow, BUFFER_SIZE, "%D %T", gmtime( &now1.tv_sec ) );
        printf("%s.%09ld msg bis : DEBUT THREAD",strNow,now1.tv_nsec);
        Donnee* p2 = (Donnee*)data1;
        int client = p2->client;
        int longueur = p2->longueur;
        int thread = p2->index;
        int cpt_img = p2->cpt;
        printf(" THREAD %d CLI %d IMG %d\n",thread,client,cpt_img);
        p2->thread_check[thread] = 0; // le thread est bien lancer
    
      
        //pthread_cond_broadcast( &cond_var);
        p2->tab_launch[client]=0; // on peut RAZ
        timespec_get( &now2, TIME_UTC );
         strftime( strNow, BUFFER_SIZE, "%D %T", gmtime( &now2.tv_sec ) );
        printf("%s.%09ld msg bis : p2 tab launch %d cli %d  \n",strNow,now2.tv_nsec,p2->tab_launch[client],client); 
        timespec_get( &now3, TIME_UTC );  
        strftime( strNow, BUFFER_SIZE, "%D %T", gmtime( &now3.tv_sec ) );
        printf("%s.%09ld msg bis : on est dans le thread %d client %d \n",strNow,now3.tv_nsec,thread,client);
        //printf("reconstruction img %d \n",p2->cpt);
        //Donnee* p = (Donnee*)malloc(sizeof(Donnee)); // g++
       // printf("longueur %d id-cli %d\n",p2->longueur,p2->client);
        int reconstruc[longueur];
        for(int j = 0;j<longueur;j++)
        {
            reconstruc[j]=img_ino[client][j];
            //printf("%d ",reconstruc[j]);
        }
        
        int x = sizeof(reconstruc)/sizeof(reconstruc[0]);
        std::vector<uchar> dest(reconstruc,reconstruc+x);
        cv::Mat dst = cv::imdecode(dest,1);
        char msg[9];
        
        timespec_get( &now4, TIME_UTC );
        strftime( strNow, BUFFER_SIZE, "%D %T", gmtime( &now4.tv_sec ) );
        printf("%s.%09ld msg bis : on a reconstruit l'image %d client %d \n",strNow,now4.tv_nsec,cpt_img,client);
        sprintf(msg,"dst%02d.jpg",cpt_img);
        //try
        //{
            cv::imwrite(msg,dst);
        //}
       /* catch (cv::Exception& e)
        {
            printf("j'ai attrapé l'erreur thread %d client %d\n reconstruc : \n",thread,client);
            for(int j = 0;j<longueur;j++)v
                printf("%d ",reconstruc[j]);
            printf("img ino : \n");
            for (int j = 0;j<100000;j++)
                        img_ino[client][j];
            printf("\n");
            const char* err_msg = e.what();
            std::cout << "exception caught: " << err_msg << std::endl;
    
        }*/
        // il ne faut pas raz pr eviter erreur de img empty  
        
        p2->tab[thread]=0; // on libère le thread
        p2->cpt1--;
        p2->reponse[client]=1000;
    
        timespec_get( &now5, TIME_UTC );
        strftime( strNow, BUFFER_SIZE, "%D %T", gmtime( &now5.tv_sec ) );
        printf("%s.%09ld msg bis : END OF THREAD %d CLI %d IMG %d \n",strNow,now5.tv_nsec,thread,client,cpt_img);
        
    //    pthread_exit(NULL);
    }
    
    
    


    le code du client :

    // udp client driver program
    #include <stdio.h>
    #include <strings.h>
    #include <sys/types.h>
    #include <arpa/inet.h>
    #include <sys/socket.h>
    #include<netinet/in.h>
    #include<unistd.h>
    #include<stdlib.h>
    #define PORT 5000
    #define MAXLINE 1000
    
    //lisa 
    #include <stdlib.h>
    #include <unistd.h>
    #include <netdb.h>
    #include <vector>
    #include <iostream>
    #include <ctime>
    #include <opencv2/core/core.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    #include <opencv2/videoio/videoio.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/imgcodecs/imgcodecs.hpp>
    #define TAILLE_PACK 10000
    #define N 4 // entête
    
    #define BUFFER_SIZE 50
    
    using namespace cv;
    using namespace std; 
    //g++ -Wall -o cli2 cli2.cpp -lopencv_core -lopencv_highgui -lopencv_videoio -lopencv_imgcodecs 
    
    void my_delay(int i) ;
    int main()
    {
    	clock_t ti,tf;
    	float t_tot;
    	int buffer[N+TAILLE_PACK]; //data a transmettre
    	int sockfd;
    	struct sockaddr_in servaddr;
    	int nico = 0;
    	int mica=0;
    	struct timespec now1,now2,now3,now4,now5,now6,now7,now8,now9,now10;
    	char strNow[ BUFFER_SIZE ];
    	
    	// clear servaddr
    	bzero(&servaddr, sizeof(servaddr));
    	servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    	servaddr.sin_port = htons(PORT);
    	servaddr.sin_family = AF_INET;
    	
    	// create datagram socket
    	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    	if (sockfd == -1)
    		{
    			printf("Could not create socket \n");
    		}
          
    	// connect to server
    	timespec_get( &now1, TIME_UTC );
        strftime( strNow, BUFFER_SIZE, "%D %T", gmtime( &now1.tv_sec ) );
    	if(connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
    	{
    		printf("\n Error : Connect Failed \n");
    		exit(0);
    	}
    	else printf("%s.%09ld Connecté !cli2 \n",strNow,now1.tv_nsec);
    
    
    	while (nico == 0)
    	{ 
    		//my_delay(1);
    		mica++;
    		if(mica == 500)
    			nico = 10;
    
    		//envoie d'une image
    		Mat src = imread("3.jpg", IMREAD_COLOR);
    
    	//creation de l'entête
    	buffer[0]=2; //id_cli
    	buffer[1]=0; //envoie length
    	buffer[2]=1; //zone de selec
    
    	//COMPRESSION OPENCV DE IMAGE DS UN VECTEUR 1o
    	std::vector<uchar> buf;
    	imencode(".jpg",src,buf); // on envoie l'image compresser dans buf
    
    	//affichage des matrices
    	//for(int i=0;i<buf.size();i++)
    	//	printf("%d \n",buf[i]);
    	
    	int length = buf.size();
    	int inter[length]; // pour eviter les pb de caractères
    	std::copy(buf.begin(),buf.end(),inter);
    	/*for(int i=0;i<buf.size();i++)
    		printf("%d ",inter[i]);*/
    
    	buffer[3]=length; // on ajoute à l'entête la length
    	
    	//TRAME DE DEBUT
    	timespec_get( &now2, TIME_UTC );
        strftime( strNow, BUFFER_SIZE, "%D %T", gmtime( &now2.tv_sec ) );
    	printf("%s.%09ld Envoie de la taille cli2! \n",strNow,now2.tv_nsec);
    	// request to send datagram no need to specify server address in sendto connect stores the peers IP and port
    	int end1 =1;
    	int recep1;
    	struct timeval timeout={0,500}; // quand 2 clients arrivent successivement
        setsockopt(sockfd,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(struct timeval)); // recvfrom non bloquant après 2 secondes
    	while (end1 ==1) //tq j'ai pas reçu une reponse du serveur
      	{
      		sendto(sockfd,(int *) buffer,N+TAILLE_PACK,MSG_CONFIRM, (struct sockaddr*)&servaddr, sizeof(servaddr));
      		recvfrom(sockfd, &recep1, sizeof(int), 0, (struct sockaddr*)NULL, NULL);
      		if(recep1 == 300)
      			end1 = 2;
      		
      	}
      	timespec_get( &now3, TIME_UTC );
        strftime( strNow, BUFFER_SIZE, "%D %T", gmtime( &now3.tv_sec ) );
      	printf("%s.%09ld trame de start envoyer, passons à la suite cli2!\n",strNow,now3.tv_nsec);
      	timeout={0,0}; // quand 2 clients arrivent successivement
        setsockopt(sockfd,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(struct timeval)); // recvfrom redevient bloquant après cette étape
    	
      	//printf("a = %d \n",a);
    	//MTN envoie data
    	buffer[1]=1;
    
    	//envoie par frame de 10 000 bits
    	timespec_get( &now4, TIME_UTC );
        strftime( strNow, BUFFER_SIZE, "%D %T", gmtime( &now4.tv_sec ) );
    	printf("%s.%09ld Envoie de l'image compressée cli2! \n",strNow,now4.tv_nsec);
    	int message_index = 0;
    	int r = length % TAILLE_PACK;
    	int num_message = (length-r)/TAILLE_PACK; //=7 70000/10000
    	int cpt=0;
    	ti = clock();
    	while(message_index < num_message)
    	{
    		timespec_get( &now5, TIME_UTC );
        	strftime( strNow, BUFFER_SIZE, "%D %T", gmtime( &now5.tv_sec ) );
    		printf("%s.%09ld index %d cli2\n",strNow,now5.tv_nsec,message_index);
    		//prepare data
    		buffer[3]=message_index;
    		memcpy(&buffer[4],&inter[cpt],TAILLE_PACK*sizeof(int)); // on met les data //ça se passe pas bien
      		//visiblement c'est ici que le printf est important 
      		//for(int i=4;i<TAILLE_PACK+4;i++) // afficher matrice
      		//	printf("%d ",buffer[i]);
      		//printf("\n");
    		sendto(sockfd,(int *) buffer,(N+TAILLE_PACK)*sizeof(int),MSG_CONFIRM, (struct sockaddr*)&servaddr, sizeof(servaddr));
    		message_index++;
    		cpt+=TAILLE_PACK;
    		
    	}
    
    	//TRAME DE FIN
    	buffer[3]=message_index;
    	timespec_get( &now6, TIME_UTC );
        strftime( strNow, BUFFER_SIZE, "%D %T", gmtime( &now6.tv_sec ) );
    	printf("%s.%09ld index %d cli2\n",strNow,now6.tv_nsec,message_index); // = 7
    	memcpy(&buffer[4],&inter[length-r],r*sizeof(int)); 
    	//for(int i=4;i<r+4;i++)
      	//		printf("%d ",buffer[i]); 
      	//printf("\n");
    	//attention après r on envoie du bulshit
    	sendto(sockfd,(int *) buffer,(N+TAILLE_PACK)*sizeof(int),MSG_CONFIRM, (struct sockaddr*)&servaddr, sizeof(servaddr));
      	tf = clock();
     	t_tot = (tf-ti);
     	//printf("t_tot %f \n t_tot %f s\n",t_tot,t_tot*1e-6);
      	//printf("c = %d\n",c);
    
      	int end = 0;
      	socklen_t len;
    	len=sizeof(servaddr);
    	int recep;
    	//boucle pour renvoyer les trames
      	while (end == 0)
      	{
      		timespec_get( &now7, TIME_UTC );
        	strftime( strNow, BUFFER_SIZE, "%D %T", gmtime( &now7.tv_sec ) );
      		printf("%s.%09ld j'attend un msg du serveur cli2\n",strNow,now7.tv_nsec);
    		recvfrom(sockfd, &recep, sizeof(int), 0, (struct sockaddr*)NULL, NULL);
    		timespec_get( &now8, TIME_UTC );
        	strftime( strNow, BUFFER_SIZE, "%D %T", gmtime( &now8.tv_sec ) );
    		printf("%s.%09ld je dois envoyer la trame %d cli2\n",strNow,now8.tv_nsec,recep);
    		if(recep != 100)
    		{
    			buffer[3]=recep;
    			if(recep == num_message) // si c'est la trame de fin
    			{
    				memcpy(&buffer[4],&inter[length-r],r*sizeof(int));
    				//for(int i = 4;i<r+4;i++)
    				//	printf("%d ",buffer[i]);
    			}
    			else 
    			{
    				memcpy(&buffer[4],&inter[recep*TAILLE_PACK],TAILLE_PACK*sizeof(int));
    				//for(int i = 4;i<TAILLE_PACK+4;i++)
    				//	printf("%d ",buffer[i]);
    			}
    			sendto(sockfd,(int *) buffer,(N+TAILLE_PACK)*sizeof(int),MSG_CONFIRM, (struct sockaddr*)&servaddr, sizeof(servaddr));
    		}
    		if (recep == 100)
    			end = 1;
      	}
    
      	int end3 = 0;
      	//timeout={0,500}; // quand 2 clients arrivent successivement
        //setsockopt(sockfd,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(struct timeval));
      	while(end3 ==0)
      	{
      		//on attend la reponse du serveur
      		timespec_get( &now9, TIME_UTC );
        	strftime( strNow, BUFFER_SIZE, "%D %T", gmtime( &now9.tv_sec ) );
      		printf("%s.%09ld j'attend la reponse du serveur cli2 \n",strNow,now9.tv_nsec);
      		recvfrom(sockfd, &recep, sizeof(int), 0, (struct sockaddr*)NULL, NULL);
      		if(recep == 1000)
      			end3 = 1;
    		
      	}
      	timespec_get( &now10, TIME_UTC );
        strftime( strNow, BUFFER_SIZE, "%D %T", gmtime( &now10.tv_sec ) );
      	printf("%s.%09ld adieu cli2! \n",strNow,now10.tv_nsec);
      // close the descriptor
    	}
    	close(sockfd);
    }
    
    
    //recvfrom(sockfd, &buffer, sizeof(int), 0, (struct sockaddr*)NULL, NULL);
    /*	socklen_t len;
    	len=sizeof(servaddr
    
    	*/
    
    void my_delay(int i)    /*Pause l'application pour i seconds*/
    {
        clock_t start,end;
        start=clock();
        while(((end=clock())-start)<=i*CLOCKS_PER_SEC);
    }

    j'ai le même code pour un deuxième client qui charge une image différente et un id différent. De manière aléatoire, dans les logs se passe la chose suivante :

    05/05/22 12:41:24.227572549 msg 11 : missing trame 6 client 2
    05/05/22 12:41:24.227575793 msg 11 : missing trame 7 client 2
    05/05/22 12:41:24.227579333 msg 5 : Reconstruction classique
    05/05/22 12:41:24.227605142 msg 6 : le client 3 a lancer le thread 0
    05/05/22 12:41:24.227609027 msg 2 : index 3 client 2
    05/05/22 12:41:24.227610952 msg 3 : CLI 3 raz 1 cpt_img_f 0
    05/05/22 12:41:24.227611433 msg 4 : CLI 2 raz 0 cpt_img_f 4
    05/05/22 12:41:24.227614321 msg 2 : index 4 client 2
    05/05/22 12:41:24.227616247 msg 3 : CLI 3 raz 1 cpt_img_f 0
    05/05/22 12:41:24.227616711 msg 4 : CLI 2 raz 0 cpt_img_f 5

    le thread 0 est lancé mais rien n'est print de ce qui provient de se thread. Dans la suite du programme ce thread étant bloqué les reconstructions appellent uniquement les threads 1,2,3,4.

    Un fonctionnement normal, on obtient les logs suivant :

    05/05/22 12:41:24.222192553 msg 11 : missing trame 6 client 2
    05/05/22 12:41:24.222195758 msg 11 : missing trame 7 client 2
    05/05/22 12:41:24.222199112 msg 5 : Reconstruction classique
    05/05/22 12:41:24.222228912 msg 6 : le client 3 a lancer le thread 0
    05/05/22 12:41:24.222237805 msg bis : DEBUT THREAD THREAD 0 CLI 3 IMG 115
    05/05/22 12:41:24.222255027 msg bis : p2 tab launch 0 cli 3  
    05/05/22 12:41:24.222247180 msg 2 : index 5 client 2
    05/05/22 12:41:24.222259243 msg 3 : CLI 3 raz 1 cpt_img_f 0
    05/05/22 12:41:24.222263698 msg 4 : CLI 2 raz 0 cpt_img_f 6
    05/05/22 12:41:24.222265395 msg 14 : RAZ client 3
    05/05/22 12:41:24.222256331 msg bis : on est dans le thread 0 client 3
    05/05/22 12:41:24.222274193 msg 15 : on a retourner la reponse finale 1000 au client 3
    05/05/22 12:41:24.222279489 msg 3 : CLI 3 raz 0 cpt_img_f 0
    05/05/22 12:41:24.222280454 msg 4 : CLI 2 raz 0 cpt_img_f 6
    05/05/22 12:41:24.222281367 msg 7 : ON REGARDE CLI QUI N'ONT PAS PARLER DEPUIS LONGTEMPS
    05/05/22 12:41:24.222282157 msg 8 : tf 500270; ti 500215; diff 55
    05/05/22 12:41:24.222283139 msg 9 : cpt 6 tab 8 cli 2
    05/05/22 12:41:24.222284212 msg 11 : missing trame 6 client 2
    05/05/22 12:41:24.222289079 msg 11 : missing trame 7 client 2
    05/05/22 12:41:24.222296539 msg 2 : index 6 client 2
    05/05/22 12:41:24.222299077 msg 3 : CLI 3 raz 0 cpt_img_f 0
    05/05/22 12:41:24.222299975 msg 4 : CLI 2 raz 0 cpt_img_f 7
    05/05/22 12:41:24.222304613 msg 3 : CLI 3 raz 0 cpt_img_f 0
    05/05/22 12:41:24.222305625 msg 4 : CLI 2 raz 0 cpt_img_f 7
    05/05/22 12:41:24.222306593 msg 7 : ON REGARDE CLI QUI N'ONT PAS PARLER DEPUIS LONGTEMPS
    05/05/22 12:41:24.222307347 msg 8 : tf 500296; ti 500291; diff 5
    05/05/22 12:41:24.222308424 msg 9 : cpt 7 tab 8 cli 2
    05/05/22 12:41:24.222309488 msg 11 : missing trame 7 client 2
    05/05/22 12:41:24.222318221 msg 3 : CLI 3 raz 0 cpt_img_f 0
    05/05/22 12:41:24.222319248 msg 4 : CLI 2 raz 0 cpt_img_f 7
    05/05/22 12:41:24.222320176 msg 7 : ON REGARDE CLI QUI N'ONT PAS PARLER DEPUIS LONGTEMPS
    05/05/22 12:41:24.222320820 msg 8 : tf 500309; ti 500291; diff 18
    05/05/22 12:41:24.222321845 msg 9 : cpt 7 tab 8 cli 2
    05/05/22 12:41:24.222322894 msg 11 : missing trame 7 client 2
    05/05/22 12:41:24.222330958 msg 2 : index 6 client 2
    05/05/22 12:41:24.222332868 msg 3 : CLI 3 raz 0 cpt_img_f 0
    05/05/22 12:41:24.222333772 msg 4 : CLI 2 raz 0 cpt_img_f 7
    05/05/22 12:41:24.222338221 msg 2 : index 7 client 2
    05/05/22 12:41:24.222339789 msg 3 : CLI 3 raz 0 cpt_img_f 0
    05/05/22 12:41:24.222340662 msg 4 : CLI 2 raz 0 cpt_img_f 8
    05/05/22 12:41:24.222341533 msg 5 : Reconstruction classique
    05/05/22 12:41:24.222366966 msg 6 : le client 2 a lancer le thread 1
    05/05/22 12:41:24.222369870 msg bis : DEBUT THREAD THREAD 1 CLI 2 IMG 116
    05/05/22 12:41:24.222372247 msg 2 : index 7 client 2
    05/05/22 12:41:24.222374704 msg 3 : CLI 3 raz 0 cpt_img_f 0
    05/05/22 12:41:24.222375624 msg 4 : CLI 2 raz 1 cpt_img_f 0
    05/05/22 12:41:24.222377760 msg 14 : RAZ client 2
    05/05/22 12:41:24.222372455 msg bis : p2 tab launch 0 cli 2  
    05/05/22 12:41:24.222380629 msg bis : on est dans le thread 1 client 2
    05/05/22 12:41:24.222382793 msg 15 : on a retourner la reponse finale 1000 au client 2
    05/05/22 12:41:24.222387185 msg 3 : CLI 3 raz 0 cpt_img_f 0
    05/05/22 12:41:24.222388004 msg 4 : CLI 2 raz 0 cpt_img_f 0
    05/05/22 12:41:24.224900699 msg bis : on a reconstruit l'image 115 client 3
    05/05/22 12:41:24.225475718 msg bis : on a reconstruit l'image 116 client 2
    05/05/22 12:41:24.226909972 msg 1 : ON A RECU TRAME DE START




    05/05/22 12:41:24.226913755 msg 3 : CLI 3 raz 0 cpt_img_f 0
    05/05/22 12:41:24.226915189 msg 4 : CLI 2 raz 0 cpt_img_f 0
    05/05/22 12:41:24.226985191 msg 2 : index 0 client 3
    05/05/22 12:41:24.226989791 msg 3 : CLI 3 raz 0 cpt_img_f 1
    05/05/22 12:41:24.226991090 msg 4 : CLI 2 raz 0 cpt_img_f 0
    05/05/22 12:41:24.226995305 msg 2 : index 1 client 3
    05/05/22 12:41:24.226997614 msg 3 : CLI 3 raz 0 cpt_img_f 2
    05/05/22 12:41:24.226998483 msg 4 : CLI 2 raz 0 cpt_img_f 0
    05/05/22 12:41:24.227001920 msg 2 : index 2 client 3
    05/05/22 12:41:24.227004111 msg 3 : CLI 3 raz 0 cpt_img_f 3
    05/05/22 12:41:24.227004921 msg 4 : CLI 2 raz 0 cpt_img_f 0
    05/05/22 12:41:24.227008237 msg 2 : index 3 client 3
    05/05/22 12:41:24.227010410 msg 3 : CLI 3 raz 0 cpt_img_f 4
    05/05/22 12:41:24.227011202 msg 4 : CLI 2 raz 0 cpt_img_f 0
    05/05/22 12:41:24.227014826 msg 2 : index 4 client 3
    05/05/22 12:41:24.227031039 msg 3 : CLI 3 raz 0 cpt_img_f 5
    05/05/22 12:41:24.227031953 msg 4 : CLI 2 raz 0 cpt_img_f 0
    05/05/22 12:41:24.227035709 msg 2 : index 5 client 3
    05/05/22 12:41:24.227037952 msg 3 : CLI 3 raz 0 cpt_img_f 6
    05/05/22 12:41:24.227038786 msg 4 : CLI 2 raz 0 cpt_img_f 0
    05/05/22 12:41:24.227176220 msg bis : END OF THREAD 0 CLI 3 IMG 115

    Comment est-ce possible que je n'ai pas d'erreur à la création du thread mais que pourtant il se passe rien ?

    Merci à vous :)

    • Partager sur Facebook
    • Partager sur Twitter
      6 mai 2022 à 14:13:25

      Il dit quoi le débogueur ?
      • Partager sur Facebook
      • Partager sur Twitter
      Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
        6 mai 2022 à 17:13:35

        Pas sur que tu auras beaucoup d'aide avec un code comme. Plus personne (de sérieux) ne code comme ça depuis 20 ans. Et ceux qui savent coder comme ça savent à quel point c'est galère et n'entrent pas dans ce type de code sauf très bonne raison.
        • Partager sur Facebook
        • Partager sur Twitter

        Serveur udp multithreading

        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
        • Editeur
        • Markdown