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

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

Réseau C Discussion :

Client / serveur fork/pipe


Sujet :

Réseau C

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2021
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2021
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Client / serveur fork/pipe
    Bonjour je fais appel à votre aide car j'ai un problème dans mon programme. Je m'explique j'ai un programme serveur.c et client.c, dans le serveur.c j'utiliser fork() pour que mon serveur écoute deux clients mais du coup les données ne sont pas partagés et on m'a conseillé d'utiliser pipe() mais cela fait bloquer un des deux clients et je n'arrive pas à comprendre pourquoi, (je suis novice en programmation). Merci d'avance de votre aide car je suis un peu désespéré.

    serveur.c
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    #include <stdio.h>
    #include <sys/socket.h>
    #include <stdlib.h>
    #include <netinet/in.h>
    #include <string.h>
    #include <pthread.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <time.h>
    #define NB_J 2
    #define NB_MANCHE 10
    #define SIZE_BUFF 50
     
     
    struct sockaddr_in serv;
    int fd;
    int conn;
    char message[SIZE_BUFF] = "";
    int nbjoueur=0;
    int joueur[NB_J];
    int manchecourante=2;
    int nbcoups=0;
    char cartesjoueur[NB_J][NB_MANCHE];
    char cartejoue [NB_J*NB_MANCHE];
     
    void initcarte();
    void affichecartes();
    char* cartedejoueur(char* infoj,int joueur,int manchec);
    void joue(int j, int coup);//joue la premiere carte du tableau du joueur qui joue
    int verif();//verifie si la manche est perdu ou gagné
    void trie();//trie les carte de chaque joueur dans l'ordre croissant
     
    void main(int argc, char** argv)
    {
     
    	printf("Démarrage du jeu...\n");
    	serv.sin_family = AF_INET;
    	serv.sin_port = htons(strtol(argv[1], NULL, 10));
    	serv.sin_addr.s_addr = INADDR_ANY;
    	fd = socket(AF_INET, SOCK_STREAM, 0);
    	bind(fd, (struct sockaddr *)&serv, sizeof(serv));
    	listen(fd,5);
    	initcarte();
    	int nbcoups=0;
       //int comIntern[2];
      // pipe(comIntern);
    	while(nbjoueur<NB_J)
    	{
    		conn = accept(fd, (struct sockaddr *)NULL, NULL);
    		joueur[nbjoueur]=conn;
    		cartesjoueur[nbjoueur][0]=conn;
    		nbjoueur++;
    		printf("Le joueur %d viens de se connecter !\n",conn);
    		printf("Il y a %d joueurs\n",nbjoueur);
    		printf("%d joueurs - %d %d %d",nbjoueur,joueur[0],joueur[1]);
       }
       affichecartes();
    	for (int t=0; t<NB_J; t++)
    	{
     
    		if(fork()==0)
    		{
    			char infoj[SIZE_BUFF]="";
    			send(joueur[t], cartedejoueur(infoj,(joueur[t]),manchecourante), SIZE_BUFF, 0);
    			while(recv(joueur[t], message, SIZE_BUFF, 0)) 
    			{
    				printf("\nLe joueur %d a jouer \n",joueur[t]);
    				joue((joueur[t]-joueur[0]), nbcoups);
    				nbcoups++;
    			//	close(comIntern[0]);
    			//   write(comIntern[1],cartejoue,(	NB_J*NB_MANCHE));
    				//close(comIntern[1]);
    				for(int i=0;i<2;i++)
    				{	
    					send(joueur[i], cartedejoueur(infoj,i,manchecourante), SIZE_BUFF, 0);
    					//send(joueur[i], cartejoue, SIZE_BUFF, 0);
    				}
    				if(nbcoups==(NB_J*manchecourante))
    				{
    					if(verif()==0)
    					{
    						manchecourante++;
     
    						for(int p=0;p<2;p++)
    						{	
    							send(joueur[p], cartejoue, SIZE_BUFF, 0);
    							send(joueur[p], "Manche gagner, niveau suivant", SIZE_BUFF, 0);
    						}
    						bzero(cartejoue,(NB_J*NB_MANCHE));
    					}
    				}		
    			}
    		}
    	}
    	while(1)
    	{
    		/*
    		char buffer[100];
    		close(comIntern[1]);
    		if(read(comIntern[0],buffer,100))
    		{
    			//printf("data%s",buffer);					
    		}
    		close(comIntern[0]);*/
    	} 
    }
     
    void initcarte()
    {
    	srand(time(NULL));
    	for(int i=0;i<NB_J;i++)
    	{
    		for(int j=1;j<=NB_MANCHE;j++)
    		{	
    			cartesjoueur[i][j]=rand()%100;	
    		}	
    	}
    	trie();
    }
     
    void trie()
    {
    	int temp;
    	for(int r=0;r<100;r++)
    	{
    		for(int i=0;i<NB_J;i++)
    		{
    			for(int j=1;j<NB_MANCHE;j++)
    			{
    				if(cartesjoueur[i][j]>cartesjoueur[i][j+1])
    				{
    					temp=cartesjoueur[i][j];
    					cartesjoueur[i][j]=cartesjoueur[i][j+1];
    					cartesjoueur[i][j+1]=temp;
    				}
    			}		
    		}
    	}
     
     
    }
     
     
     
     
     
    void affichecartes()
    {
    	for(int i=0;i<NB_J;i++)
    	{
    		printf("\nCartes du joueur %d:",cartesjoueur[i][0]);
    		for(int j=1;j<NB_MANCHE;j++)
    		{
    			printf("%d  ",cartesjoueur[i][j]);	
    		}
    		printf("\n");	
    	}
    } 
     
     
    //renvoi dans un tableau les cartes du joueur d'id passé en paramètre 
    char* cartedejoueur(char* infoj,int joueur, int manchec)
    {
     
    	for(int i=1;i<=manchec;i++)
    		snprintf(infoj,SIZE_BUFF,"%s-%d",infoj,cartesjoueur[joueur][i]);
    	return infoj;
    }
     
    void joue(int j, int coup)
    {
    	int i =0;
    	int t=1;
    	do 
    	{
     
    		if(cartesjoueur[j][t]!=0)
    		{
    			printf("ca joue\n");
    			cartejoue[coup]=cartesjoueur[j][t];
    			cartesjoueur[j][t]=0;
    			i=1;
    		}
    		else 
    		{
    			t++;
    		}
    	}
    	while(i==0);
    	printf("cartes jouées");
    	for(int q=0;q<10;q++)
    	{
    		printf("%d-",cartejoue[q]);
     
    	}
     
    }
     
     
    int verif()
    {
    	int j=0;
    	for(int i=0;i<(NB_J*NB_MANCHE);i++)
    	{
    		if(cartejoue[i+1]<cartejoue[i])
    		{
    			j++;
    		}
    	}
    	return j;
     
    }
    client.c
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    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
    #include <stdio.h>
    #include <sys/socket.h>
    #include <stdlib.h>
    #include <netinet/in.h>
    #include <string.h>
    #include <pthread.h>
    #include <arpa/inet.h>
     
    struct sockaddr_in serv;
    int fd;
     
     
    char envoi[100] = "";
    char recu[100]="";
    int THI = 0;
     
     
    void* recevoir(void* infojeu);
    void* env(void* cartej);
     
     
    void error(char *msg)
    {
        perror(msg);
        exit(0);
    }
     
     
    void main(int argc, char** argv){
     
    THI = strtol(argv[2], NULL, 10);
    fd = socket(AF_INET, SOCK_STREAM, 0);
    serv.sin_family = AF_INET;
    serv.sin_port = htons(strtol(argv[1], NULL, 10));
    inet_pton(AF_INET, "localhost", &serv.sin_addr);
    if(connect(fd, (struct sockaddr *)&serv, sizeof(serv))<0)
    {
    	error("Serveur fermer");
    }
     	pthread_t threadRecv;
    	pthread_t threadSend;
       pthread_create(&threadRecv, NULL, recevoir, (void*)&recu);
     	pthread_create(&threadSend, NULL, env, (void*)&envoi);
    	while(1)
    	{
     
    	};
     
     
    }
     
    void* recevoir(void* infojeu)
    {
    	while(1)
    	{
    		if(recv(fd,recu,100,0)>0)
    		{
    			printf("%s",recu);
    			bzero(recu,100);
    			printf("\nAppuyez sur Entrée pour jouer: \n(vous jouerez votre plus petite carte)\n");
     
    		}
    		else
    		{
    			printf("vous etes deconnecte du serveur\n");
    			exit(1);
    		}
    	}
     
    }
     
    void* env(void* cartej)
    {
    	while(1)
    	{
    		//printf("\nAppuyez sur Entrée pour jouer: \n(vous jouerez votre plus petite carte)\n");
            envoi[0] = '0'+THI;
            envoi[1] = '-';
            fgets(envoi+2, 98, stdin);
     
        	send(fd, envoi, strlen(envoi), 0);
        	bzero(envoi,100);
    	};
    }
    Fichiers attachés Fichiers attachés

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Avant de vouloir parler de fork, pipe ou quoi que ce soit, il manque des bases.
    Les fonctions retournent des code d'erreur qu'il faut vérifier pour s'assurer que tout s'est bien passé.
    Ensuite il faut savoir qu'un socket est bloquant par défaut.
    - accept est bloquant
    - recv est bloquant
    - recv(socket, buffer, maxsize) reçoit jusqu'à maxsize octets mais peut retourner avant
    - send est bloquant pour mettre en file d'envoi les données
    Puis il faut comprendre ce que tu écris, parce que dès le début
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while(nbjoueur<NB_J) {... accept(...);...}
    Donc tant que tu as pas 2 joueurs, tu attends des joueurs ? Étrange.
    Après ton client a lui-même des threads pour envoyer un truc, donc le server va vite bloquer sur recv je pense.

    Pi franchement, y'a plus simple que fork et autres. Tu pourrais créer un simple thread, ou utiliser le mode non bloquant.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2021
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2021
    Messages : 2
    Points : 1
    Points
    1
    Par défaut
    Oui le but est que le jeu se lance dès que deux clients sont connecté et le but de ce programme était de travailler sur le fork.

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    fork va créer un nouveau processus qui aura ses propres variables.
    Pour partager la mémoire, faut utiliser la mémoire partagée https://stackoverflow.com/a/13274800
    Tout cela est bien complexe par rapport à l'utilisation de socket non bloquant ou threads...
    D'où tu sors ce truc pour travailler sur fork ? C'est vraiment un cas tordu qui ne devrait pas utiliser fork imo.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

Discussions similaires

  1. Clients/serveur & Named Pipe, besoins de Mutex ?
    Par narfight dans le forum Windows Forms
    Réponses: 1
    Dernier message: 13/07/2013, 11h19
  2. Client serveur fork
    Par majong dans le forum Flash
    Réponses: 1
    Dernier message: 03/07/2010, 19h50
  3. serveur multi client avec fork()
    Par deby23 dans le forum Réseau
    Réponses: 17
    Dernier message: 11/09/2007, 16h32
  4. Réponses: 4
    Dernier message: 06/01/2007, 21h42
  5. Langage le mieux adapté pour application client serveur ?
    Par guenus dans le forum Débats sur le développement - Le Best Of
    Réponses: 4
    Dernier message: 17/06/2002, 15h46

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