Threads, fonction et mutex ? [Résolu]

Messages postés
28
Date d'inscription
vendredi 1 janvier 2010
Dernière intervention
10 août 2010
- - Dernière réponse : cs_Adict
Messages postés
28
Date d'inscription
vendredi 1 janvier 2010
Dernière intervention
10 août 2010
- 10 mai 2010 à 19:37
bonjour à tout le monde

dans mon projet de créer un tchat il faut que j'applique sur le client un thread qui exécute une autre fonction qui doit lire les messages.

Hors je doit mettre la fonction en dehors de "main" et la fonction pour lire les messages ne reconnais plus aucune variables ni même les sockets.
Comment puis-je faire ? utiliser les mutex ? de plus je ne sais pas trop comment mettre en place cela surtout que le thread gère une boucle infinie.

voila déjà se que j'ai fait pour le moment. (je vous ais mis seulement les parties qui posent problème car sinon c'est trop long)

void* message(void* data);
 
 
int main(int argc, char *argv[])
{
 
/*
 
..............Variables et socket................
 
*/
 
pthread_t thread;/* crée un thread */
pthread_create(&thread, NULL, message, NULL);/* Permet d'exécuter le fonction message en parallèle */
 
while (1)
{ /* début boucle wirthe */
 
system("CLS");
 
printf("\n%s : ", pseudo);
 
    fgets(chaine, sizeof chaine, stdin);
    clean(chaine);
    
   
    snprintf(buffer, sizeof(buffer), "%s : %s \n", pseudo, chaine);
    
   send(s, buffer, strlen(buffer), 0); 
 
    if  ( strcmp( chaine, "exit" ) == 0 )
    { 
 
       goto fin; /* je sais goto c'est pas bien mais c'est juste pour faire les testes en attendant :p */
        
    }  
} /* fin boucle writhe */  
pthread_join(thread, NULL);
 
/*
.........fermeture socket..............
*/
 
return o;
}
 
void* message(void* data); /* Fonction de réception de message */
      {
   while(1)  /* boucle de réception des messages */
   {
 memset(buffer, '\0', sizeof(buffer));
 n = recv(s, buffer, sizeof(buffer) - 1, 0);
 printf("%s\n",buffer);
   }
      } /* Finc de la fonction de réception des messages */        
 


Merci.

________________________________________________________________
j'ai 16 ans et j'aime l'informatique, surtout les programmes
Afficher la suite 

Votre réponse

11 réponses

Meilleure réponse
Messages postés
1108
Date d'inscription
mercredi 15 juin 2011
Dernière intervention
10 juillet 2018
3
Merci
ton message de samedi, ton revc et send me semble correct.

Sinon, tu es perdu, donc oublies les structures, surtout que tu en a pas besoin.

dans le main :
pthread_create(&thread, NULL, message, (void *)&s);


dans message :
void* message(void* data) /* Fonction de réception de message */
{
      
char buff[1024];
SOCKET *s = (SOCKET *)data;
char buff[1024];
int n; // ton main s'en fout de n
recep *pStruct = (SOCKET *)data;

while(1)  /* boucle de réception des messages */
   {
 memset(buff, '\0', sizeof(buff)); 
 n = recv(*s, buff, sizeof(buff) - 1, 0);
 printf("%s\n",buff);

   }
  
} /* Finc de la fonction de réception des messages


J'ai pas fait gaffe, ce code est le code du client ? Si c'est le serveur, ca ne marche pas. Va voir cet ex.

Merci fregolo52 3

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

Codes Sources a aidé 97 internautes ce mois-ci

Commenter la réponse de fregolo52
Messages postés
1108
Date d'inscription
mercredi 15 juin 2011
Dernière intervention
10 juillet 2018
0
Merci
tu dois passer la socket en paramètre de ton thread :

dans main :

SOCKET s;
// init sock
...
pthread_t thread;
pthread_create(&thread, NULL, message, (void *)&s);


dans ton thread :
void* message(void* data) {
SOCKET *s = (SOCKET *)data; // attention c'est un pointeur
....
}
Commenter la réponse de fregolo52
Messages postés
28
Date d'inscription
vendredi 1 janvier 2010
Dernière intervention
10 août 2010
0
Merci
Merci, ça marchais presque.

alors voila la fonction crée
void* message(void* data) /* Fonction de réception de message */
{

SOCKET *s = (SOCKET *)data;
char *buffer;
int *n;

while(1)  /* boucle de réception des messages */
   {
 memset(buffer, '\0', sizeof(buffer));
 n = recv(s, buffer, sizeof(buffer) - 1, 0);
 printf("%s\n",buffer);
   }
  
} /* Finc de la fonction de réception des messages */     


erreur:
C:\Dev-Cpp\chatbox_real\Client\main.c In function `message':

337 C:\Dev-Cpp\chatbox_real\Client\main.c [Warning] passing arg 1 of `recv' makes integer from pointer without a cast

337 C:\Dev-Cpp\chatbox_real\Client\main.c [Warning] assignment makes pointer from integer without a cast


pour pouvoir faire SOCKET *s = (SOCKET *)data; il faut donc ajouter "&s" à la place de NULL dans le thread. Comment ajouter char *buffer; et
int *n; ?

malgré ces erreurs le client compile mais je ne voit pas la chaine que j'écris mais elle est bien envoyé au serveur. (je pense que c'est le faite que j'utilise des boucle infini non ? )

________________________________________________________________
j'ai 16 ans et j'aime l'informatique, surtout les programmes
Commenter la réponse de cs_Adict
Messages postés
1108
Date d'inscription
mercredi 15 juin 2011
Dernière intervention
10 juillet 2018
0
Merci
si tu veux passer plusieurs paramètres il va falloir les mettre dans une structure et passer cette structure au thread.

s est un pointeur, donc il ne faut pas oublier le '*' :
recv(*s, .....);
Commenter la réponse de fregolo52
Messages postés
28
Date d'inscription
vendredi 1 janvier 2010
Dernière intervention
10 août 2010
0
Merci
salut alors j'ai fait la structure:
struct MaStructure 
      {
       SOCKET *s;
       char *buffer;
       int *n;
       };


mais je n'ai pas réussie en l'ajouter dans les paramètre du thread j'avais essayé de cette façon sans résulta.

pthread_create(&thread, NULL, message, (struct *)&MaStructure);


j'ai 16 ans et j'aime l'informatique, surtout les programmes
Commenter la réponse de cs_Adict
Messages postés
1108
Date d'inscription
mercredi 15 juin 2011
Dernière intervention
10 juillet 2018
0
Merci
c'est pas beau ce que tu as fait !!!

un truc simple, mais y'a bcp mieux.

struct MaStructure 
      {
       SOCKET s;
       char buffer[mets ici un taille max];
       int n;
       };


MaStructure datastruct;
datastruct.s = ...;
....
pthread_create(&thread, NULL, message, (struct *)&datastruct);


void* message(void* data) /* Fonction de réception de message */
{

MaStructure *pStruct = (SOCKET *)data;

while(1)  /* boucle de réception des messages */
   {
 memset(pStruct->buffer, '\0', sizeof(pStruct->buffer)); // là j'ai un doute sur le sizeof
 pStruct->n = recv(pStruct->s, pStruct->buffer, sizeof(pStruct->buffer) - 1, 0);
 printf("%s\n",pStruct->buffer);
   }
  
} /* Finc de la fonction de réception des messages */   
Commenter la réponse de fregolo52
Messages postés
28
Date d'inscription
vendredi 1 janvier 2010
Dernière intervention
10 août 2010
0
Merci
ok mais j'ai 2 questions.

est-ce que je peut placer
MaStructure datastruct;
datastruct.s = ...;

n'importe où dans main ? ou ça a une place bien précise ?

et que dois-je mettre à la place des trois petit point ?
j'avais pensé à ça: datastruct.s = *((struct MaStructure*)data);
Mais je pense pas que ça fonctionnera

Merci de m'aider en tout cas :)



j'ai 16 ans et j'aime l'informatique, surtout les programmes
Commenter la réponse de cs_Adict
Messages postés
1108
Date d'inscription
mercredi 15 juin 2011
Dernière intervention
10 juillet 2018
0
Merci
bah tu dois placer la déclaration où tu veux mais bien sûre avant le while.

non, dans le main, dans datastruct.s tu mets s (le même s du send de la boucle while) :
datastruct.s = s;

mais en relisant ton 1er message, je ne vois pas l'intérêt de la structure.

ton main et ton thread message peuvent (et meme, doivent) gérer leur propre buffer. Vu que chacun fait son printf.
Commenter la réponse de fregolo52
Messages postés
28
Date d'inscription
vendredi 1 janvier 2010
Dernière intervention
10 août 2010
0
Merci
ok donc je doit mettre ensuite par exemple
MaStructure datastruct;
datastruct.s =  s;
datastruct.b = buffer;
datastruct.n = n;


pour gérer leur propre buffer donc sur le client on envoi la chaine + pseudo dans le buffer qui s'envoie au serveur
le serveur lit le buffer et le renvoi au client mais j'avais pensé faire comme ça: (sa compile mais je ne sais pas si ça marche car j'ai pas terminer les structures)

Serveur
while(1)
   {
 memset(buffer, '\0', sizeof(buffer));
 n  = recv(s_client, buffer, sizeof(buffer) - 1, 0);
 printf("%s\n",buffer); 
 strcpy(buff, ("%s\n", buffer)); /*copi dans buff le buffer */
 send(s_client, buff, (int)strlen(buff), 0); /*envoi le buff au client */
   }



Client (sans les structures)
while(1)  /* boucle de réception des messages */
   {
 memset(buff, '\0', sizeof(buff)); // là j'ai un doute sur le sizeof
 n = recv(s, buff, sizeof(buff) - 1, 0);
 printf("%s\n",buff);

   }


j'ai 16 ans et j'aime l'informatique, surtout les programmes
Commenter la réponse de cs_Adict
Messages postés
28
Date d'inscription
vendredi 1 janvier 2010
Dernière intervention
10 août 2010
0
Merci
Bon je crois que je suis un peu perdu

je récapitule.

j'ai fait le structure

struct recep   
      {
       SOCKET *s; //je met des pointeurs car elles sont déjà dans main
       int *n;
      };





je ne vois franchement pas à quoi ces commandes sèvrent
MaStructure datastruct;
datastruct.s = ...; 
....


voici le code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#include <string.h>
#include <winsock2.h>
#include 

static void purger(void)
{
    int c;

    while ((c = getchar()) != '\n' && c != EOF)
    {}
}

static void clean (char *chaine)
{
    char *p = strchr(chaine, '\n');

    if (p)
    {
        *p = 0;
    }

    else
    {
        purger();
    }
}
/*------------------------------------------*/
static void purgera(void)
{
    int d;

    while ((d = getchar()) != '\n' && d != EOF)
    {}
}

static void cleaner (char *pseudo)
{
    char *q = strchr(pseudo, '\n');

    if (q)
    {
        *q = 0;
    }

    else
    {
        purgera();
    }
}

void* message(void* data);


int main(int argc, char *argv[])
{
    
    char chaine[5000];
    char pseudo[30];


/*
----------------------------------------------------
*/



WSADATA wsaData;

    if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0)
        fprintf(stderr, "La fonction WSAStartup a echoue.\n");
    else
    {
        SOCKET s;
        
        s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (s == INVALID_SOCKET)
            fprintf(stderr, "La fonction socket a echoue.\n");
        else
        {
            SOCKADDR_IN server;
            
            server.sin_family       = AF_INET;
            server.sin_addr.s_addr  = inet_addr("127.0.0.1");
            server.sin_port         = htons(5050);
            memset(&server.sin_zero, '\0', sizeof(server.sin_zero));
            
            if (connect(s, (SOCKADDR *)&server, sizeof(server)) == SOCKET_ERROR)
                fprintf(stderr, "La fonction connect a echoue.\n");
            else
            {
                char buffer[1024];
                
                int n;
                
                n = recv(s, buffer, sizeof(buffer) - 1, 0); 
                
                if (n != SOCKET_ERROR)
                {
                    buffer[n] = '\0';
                    printf("%s", buffer);
                    /*-----------------------------------------------*/
                    
                    struct recep 
      {
       SOCKET *s;
       int *n;
      };

                    system("CLS");
                    printf("Choisissez un pseudo visible par les autre membres.\n\n"); 

    printf("choix ? ");
    
    fgets(pseudo, sizeof pseudo, stdin);
    clean(pseudo);
    
printf("\n\nBienvenu %s\n", pseudo);
getch();

system("CLS"); 
                    
                    /*-----------------------------------------------*/
                          
  
  
pthread_t thread;/* crée un thread */
pthread_create(&thread, NULL, message, (void *)&datastruct);/* Permet d'exécuter le fonction message en parallèle, une erreur ici */

int compteur;
for (compteur = 0 ; compteur < 2 ; compteur++) //obligé d'employer une boucle ici car la copie du buffer ne marhcait pas
   {
   snprintf(buffer, sizeof(buffer), "user: %s, rejoint la conversation.", pseudo);
   send(s, buffer, strlen(buffer), 0);
   }

while (1)
 { /* début boucle wirthe */

printf("\n%s : ", pseudo);
 
    fgets(chaine, sizeof chaine, stdin);
    clean(chaine);
    
   
    snprintf(buffer, sizeof(buffer), "%s : %s ", pseudo, chaine);
    
   send(s, buffer, strlen(buffer), 0); 

    if  ( strcmp( chaine, "exit" ) == 0 )
    { 

       goto fin; /* je sais goto c'est pas bien mais c'est juste pour faire les testes en attendant :p */
        
    }  
 } /* fin boucle writhe */  

 

pthread_join(thread, NULL);

   

           fin: 
                    send(s, "Au revoir\n", (int)strlen("Au revoir\n"), 0); 
                    
                    
                }
                
                shutdown(s, SD_SEND);
            }
            
            closesocket(s);
        }
        
        WSACleanup();
    }
    
    return 0;
}




void* message(void* data) /* Fonction de réception de message */
{
      
char buff[1024];
recep *pStruct = (SOCKET *)data;

while(1)  /* boucle de réception des messages */
   {
 memset(buff, '\0', sizeof(buff)); 
 pStruct->n = recv(pStruct->s, buff, sizeof(buff) - 1, 0);
 printf("%s\n",buff);

   }
  
} /* Finc de la fonction de réception des messages




les erreurs:
C:\Dev-Cpp\chatbox_real\Client\main.c In function `main':

275 C:\Dev-Cpp\chatbox_real\Client\main.c `datastruct' undeclared (first use in this function)
(Each undeclared identifier is reported only once for each function it appears in.)


C:\Dev-Cpp\chatbox_real\Client\main.c In function `message':

336 C:\Dev-Cpp\chatbox_real\Client\main.c `recep' undeclared (first use in this function)
336 C:\Dev-Cpp\chatbox_real\Client\main.c `pStruct' undeclared (first use in this function)

Commenter la réponse de cs_Adict
Messages postés
28
Date d'inscription
vendredi 1 janvier 2010
Dernière intervention
10 août 2010
0
Merci
Merci beaucoup j'y vois déjà mieux
il ne me reste plus que 3 problèmes à résoudre et je pense pouvoir finaliser mon tchat

Merci encore


j'ai 16 ans et j'aime l'informatique, surtout les programmes
Commenter la réponse de cs_Adict

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.