Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1208 connectés 

  FORUM HardWare.fr
  Programmation
  C

  Erreur flagrante? Serveur (sockets + threads)

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Erreur flagrante? Serveur (sockets + threads)

n°1241883
gocho
Posté le 08-11-2005 à 23:38:13  profilanswer
 

Bien le bonjour a tous! :hello:  
 
Voila j'ai cette annee un projet tutore a faire(2e annee de dut info gestion).Pour cela je suis en train de developper un serveur multiclient en C.J'utilise donc les threads et les sockets, et je travaille sous linux (y'aura ptet du windows dans l'affaire plus tard mais c'est optionnel si le temps le permet)
Ne connaissant pas grand chose a la programmation reseau, j'ai cherche sur le net des tuto, des exemples et tout ce qui pouvait m'aider et grace a tout ca et pas mal de temps j'en ai sorti quelquechose qui devrait etre potable (non non c'est pas portable  :lol: ) :D  
 Seulement avant de continuer plus loin, et au vu de ma tres petite experience dans la prog reseau je souhaiterai savoir si dans le code de mon serveur, il vous apparait des erreurs grossieres, des failles assez moches ou memes des fuites de memoires.
Enfin je voudrais avoir au final un code si possible le plus propre possible donc je demande un peu d'aide exterieure
 

Code :
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <sys/types.h>
  5. #include <sys/socket.h>
  6. #include <netinet/in.h>
  7. #include <netdb.h>
  8. #include <unistd.h>
  9. #include <pthread.h>
  10. #ifndef  LONGUEUR_MAX
  11. #define  LONGUEUR_MAX 256
  12. #define  MAX_CLIENTS 10
  13. #define         NB_FILE_CLIENTS 5
  14. #define   PSEUDO               "Bienvenue...\nEntrez votre pseudo : "
  15. /*erreurs*/
  16. #define  ERR_OPEN_SOCK "Erreur d'ouverture de la socket!\n"
  17. #define  ERR_BIND "Erreur de bind!\n"
  18. #define  ERR_LISTEN "Erreur de listen!\n"
  19. #define  ERR_ALLOCATE_MEM_CLIENT "Erreur d'allocation memoire pour le client!\n"
  20. #define  ERR_PSEUDO "Erreur de pseudo! Celui choisi est deja en cours d'utlisation!\n"
  21. #define  ERR_WRITE "Erreur d'ecriture!\n"
  22. #define  ERR_ALLOCATE_MEM_PSEUDO "Erreur lors de l'allocation memoire pour le pseudo!\n"
  23. #define  ERR_RESEAU "Erreur de reseau!\n"
  24. #define  ERR_ACCEPT "Erreur d'acceptation d'un client\n"
  25. #endif
  26. #define PORT 1798
  27. struct s_client{
  28. pthread_t id;
  29. int socket;
  30. char * pseudo;
  31. };
  32. typedef struct s_client client;
  33. typedef struct sockaddr_in struct_socket;
  34. client tab_clients[MAX_CLIENTS];
  35. char nom_serveur[LONGUEUR_MAX];
  36. int case_libre=0;
  37. int nb_clients;
  38. /**************************************************************/
  39. /*   Creation serveur        */
  40. /**************************************************************/
  41. int creation_serveur(int port){
  42. /*variables utiles a la creation du serveur*/
  43. int sock;
  44. struct_socket adresse_socket;
  45. /*initialisation du nom du serveur*/
  46. gethostname(nom_serveur,sizeof(nom_serveur));
  47. if ((sock=socket(PF_INET,SOCK_STREAM,0))<0){
  48.  printf (ERR_OPEN_SOCK);
  49.  exit(-1);
  50. }
  51. /*initialisation du serveur*/
  52. memset(&adresse_socket,0,sizeof(struct sockaddr_in));
  53. adresse_socket.sin_family=AF_INET;
  54. adresse_socket.sin_port=htons(port); // htons convertit un entier court en entier "reseau"
  55. adresse_socket.sin_addr.s_addr=htonl(INADDR_ANY); // htonl : de meme que htons mais pour un entier long  INADDR_ANY=0 -> designe l'adresse du poste sur lequel est lance le programme  
  56. /*affectation d'un nom a la socket*/
  57. if (bind (sock,(struct sockaddr *)&adresse_socket,sizeof(struct sockaddr_in))<0){
  58.  perror (ERR_BIND);
  59.  exit(-1);
  60. }
  61. /*"initialisation" des "options" d'ecoute de la socket*/
  62. if (listen(sock,NB_FILE_CLIENTS)<0){
  63.  perror (ERR_LISTEN);
  64.  exit(-1);
  65. }
  66. return sock;
  67. }
  68. /**************************************************************/
  69. /*  Envoi de message a un seul client             */
  70. /**************************************************************/
  71. int envoi_message(int sock, char * message){
  72. if ((write(sock,message,strlen(message)))==-1){
  73.    perror(ERR_WRITE);
  74.    return 1;
  75. }
  76. return 0;
  77. }
  78. /**************************************************************/
  79. /*   Envoi de message a tous les clients sauf celui specifie  */
  80. /**************************************************************/
  81. int envoi_limite(char * message,int sock){
  82. int i;
  83. for (i=0;i<case_libre;i++){
  84.  if(tab_clients[i].socket != sock){
  85.   envoi_message(tab_clients[i].socket,message);
  86.  }
  87. }
  88. return 0;
  89. }
  90. /**************************************************************/
  91. /* Envoi d'un message a tous les clients du serveur      */
  92. /**************************************************************/
  93. int envoi_general(char * message){
  94. int i;
  95. for (i=0;i<case_libre;i++){
  96.  envoi_message(tab_clients[i].socket,message);
  97. }
  98. return 0;
  99. }
  100. /**************************************************************/
  101. /*  Depart d'un client         */
  102. /**************************************************************/
  103. void client_quit(client * client_courant,char * raison){
  104. int i,j;
  105. char buf[8192+1];
  106. if ((strcmp(raison,'\0'))>0){
  107.  snprintf(buf,8192,"%s part vers d'autres cieux...(%s)\n",client_courant->pseudo,raison);
  108. }
  109. else {
  110.  snprintf(buf,8192,"%s part vers d'autres cieux...(%s)\n",client_courant->pseudo,raison);
  111. }
  112. envoi_limite(buf,client_courant->socket);
  113. /*recherche du client dans tab_clients*/
  114. for (i=0;(tab_clients[i].socket != client_courant->socket);i++);
  115. /*liberation des ressources du client*/
  116. close(client_courant->socket);
  117. free(client_courant->pseudo);
  118. free(client_courant);
  119. /*reorganisation de tab_clients*/
  120. for (j=i+1;j<case_libre;j++){
  121.  tab_clients[j-1]=tab_clients[j];
  122. }
  123. case_libre--;
  124. nb_clients--;
  125. }
  126. /**************************************************************/
  127. /*      Acceptation d'un client par le serveur           */
  128. /**************************************************************/
  129. int client_accepte(int socket_serveur){
  130.   int socket_client;
  131.   if((socket_client = accept(socket_serveur,NULL,0)) < 0)
  132.     {
  133.       if(errno == EINTR)
  134. {
  135.   shutdown(socket_serveur,SHUT_RDWR);
  136.   close(socket_serveur);
  137.   nb_clients--;
  138.   return -1;
  139. }
  140.       else
  141. {
  142.   perror(ERR_ACCEPT);
  143.   exit(-1);
  144. }
  145.     }
  146.   fcntl(socket_client,F_SETFD,1);
  147.   return socket_client;
  148. }
  149. /**************************************************************/
  150. /*      Interaction avec le client : thread              */
  151. /**************************************************************/
  152. void * thread_client(void *args){
  153. char pseudo[255];
  154. char message_emis[8192+1];
  155. char message_recu[4096+1];
  156. int case_libre=0;
  157. int len,i;
  158. int sock=*((int *)args);
  159. client *client_courant=NULL;
  160. if ((client_courant=malloc (sizeof(struct s_client)))==NULL){
  161.  perror (ERR_ALLOCATE_MEM_CLIENT);
  162.  close (sock);
  163.  nb_clients--;
  164.  pthread_exit(NULL);
  165. }
  166. envoi_message(sock,PSEUDO);
  167.              len = read(sock,message_recu,4096);
  168.              if(len <= 0) {
  169.  printf("\nErreur\n" );
  170.  close(sock);
  171.  free(me);
  172.  client_courant = NULL;
  173.  nb_clients--;
  174.  pthread_exit(NULL);
  175. }
  176. /*recuperation du pseudo du client courant*/
  177. for (i=0;(pseudo[i]!='\0')&&(pseudo[i]!='\n');i++);  //on va a la fin du pseudo
  178. pseudo[i]='\0'; // on met un \0 pour le terminer proprement
  179. for (i=0;i<case_libre;i++){
  180.  if (strcmp(pseudo,tab_clients[i].pseudo)==0){ // si strcmp==0 alors les chaines sont identiques
  181.   if ((write(sock,ERR_PSEUDO,strlen(ERR_PSEUDO)))==-1){
  182.    perror(ERR_WRITE);
  183.   }
  184.   close (sock); //fermeture de la socket du client courant
  185.   free(client_courant); //liberation de la memoire allouee pour le client courant
  186.   nb_clients--;
  187.   pthread_exit(NULL);
  188.  }
  189. }
  190. /*initialisation de la structure du client courant*/
  191. if(client_courant->pseudo=malloc(sizeof(pseudo))==NULL){
  192.  perror (ERR_ALLOCATE_MEM_PSEUDO);
  193.  nb_clients--;
  194.  pthread_exit(NULL);
  195. }
  196. client_courant->id=pthread_self();
  197. client_courant->socket=sock;
  198. strcpy(client_courant->pseudo,pseudo);
  199. /*placement du client dans le tab_client a la premiere "case libre"*/
  200. tab_clients[case_libre]=*client_courant;
  201. case_libre++; //le prochaine case libre du tableau est un rang plus loin
  202. snprintf(message_emis,8192,"Nouveau Client : %s\n",client_courant->pseudo);
  203. message_emis[8192]='\0';
  204. if ((write(sock,message_emis,strlen(message_emis)))==-1){
  205.    perror(ERR_WRITE);
  206. }
  207. while (1){
  208.  len=read(sock,message_recu,8192); //read retourne le nombre d'octets lus, -1 en cas d'echec, 0 si rien ou en fin de fichier
  209.  if (len<=0){ //s'il y a erreur de lecture ou fin du message
  210.   client_quit(client_courant,ERR_RESEAU);
  211.   pthread_exit(NULL);
  212.  }
  213.  message_recu[len]='\0';
  214.  snprintf(message_emis,8192,"%s : %s\n",client_courant->pseudo,message_recu);
  215.  message_emis[8192]='\0';
  216.  envoi_general(message_emis);
  217. }
  218. return NULL;
  219. }
  220. /**************************************************************/
  221. /*      Fonction principale : lancement du serveur       */
  222. /**************************************************************/
  223. int main(int argc, char **argv)
  224. {
  225. int socket_serveur,socket_client;
  226. pthread_t id;
  227. socket_serveur = create_server(PORT);
  228. while(1)
  229. {
  230.  if ((socket_client = client_accepte(socket_serveur))==-1){
  231.   perror(ERR_ACCEPT);
  232.   exit(-1);
  233.  }
  234.  if(nb_clients < MAX_CLIENTS)
  235.  {
  236.   pthread_create(&id,NULL,thread_client,(void *)&socket_client);
  237.   nb_clients++;
  238.   printf("Nouveau client! Il y a actuellement %d clients sur le serveur\n",nb_clients);
  239.  }
  240.  else close(socket_client);
  241. }
  242. return 0;
  243. }


 
J'avoue c'est un peu long alors je remercie d'avance ceux qui auront la patience de tout lire et de m'aider  :)  
Merci


Message édité par gocho le 10-11-2005 à 00:14:39
mood
Publicité
Posté le 08-11-2005 à 23:38:13  profilanswer
 

n°1242802
gocho
Posté le 09-11-2005 à 23:45:01  profilanswer
 

y'as pas de fautes ? :)

n°1242803
chrisbk
-
Posté le 09-11-2005 à 23:47:42  profilanswer
 

exit, c'est moche
 

Code :
  1. if ((write(sock,message,strlen(message)))==-1)


 
a mon avis ton test est pas bon, tu dois vérifier que write te retourne bien le meme nombre d'octet que tu lui a demandé d'ecrire

Message cité 1 fois
Message édité par chrisbk le 09-11-2005 à 23:48:39
n°1242804
chrisbk
-
Posté le 09-11-2005 à 23:51:33  profilanswer
 

Code :
  1. if ((strcmp(raison,'\0'))>0){


 
tordu
 
 

Code :
  1. if (strlen(raison)>0)


 

Code :
  1. for (i=0;(pseudo[i]!='\0')&&(pseudo[i]!='\n');i++);


 
pour ce genre de chose, je trouve while plus logique est plus lisible
 
 
sinon spa trop mal, par contre je suis vraiment pas allé dans le detail

n°1242806
gocho
Posté le 10-11-2005 à 00:02:55  profilanswer
 

chrisbk a écrit :

exit, c'est moche
 

Code :
  1. if ((write(sock,message,strlen(message)))==-1)


 
a mon avis ton test est pas bon, tu dois vérifier que write te retourne bien le meme nombre d'octet que tu lui a demandé d'ecrire


 
exit C'est juste moche ou c'est deprecated (j'aime bien ce mot  :D )? return c'est mieux?
 
 
pour le write j'ai teste si ca avait pas echoue.Ce serait mieux si je faisais ca?

Code :
  1. if ((write(sock,message,strlen(message)))!=(strlen(message))


 
 

Citation :

Code :
  1. for (i=0;(pseudo[i]!='\0')&&(pseudo[i]!='\n');i++);


 
pour ce genre de chose, je trouve while plus logique est plus lisible


voui c'est sur...vais changer ca.
 
 

Citation :

sinon spa trop mal, par contre je suis vraiment pas allé dans le detail


merci.si en superficiel deja ca le fait....

n°1242808
chrisbk
-
Posté le 10-11-2005 à 00:06:54  profilanswer
 

gocho a écrit :

exit C'est juste moche ou c'est deprecated (j'aime bien ce mot  :D )? return c'est mieux?


 
juste moche, il vaut mieux faire remonter l'erreur aussi haut que possible, des fois qu'il y ait des liberations de ressources a faire

Citation :


 
pour le write j'ai teste si ca avait pas echoue.Ce serait mieux si je faisais ca?

Code :
  1. if ((write(sock,message,strlen(message)))!=(strlen(message))



 
ca te fais deux strlen, et trois appels de fonction sur une meme ligne, ca devient guere lisible
 

Citation :

size_t truc = strlen(message);


et zou avec truc
 

gocho a écrit :


merci.si en superficiel deja ca le fait....


 
bin ptet je traine trop ici, a force de voir des horreurs accablante on perds la faculté a chercher la ptite bete [:moule_bite]

n°1242809
chrisbk
-
Posté le 10-11-2005 à 00:08:27  profilanswer
 

Code :
  1. else close(sock);


 
y sort d'ou, ce sock ?
 
(bon sinon les vars globales, ca aussi c'est moche)

n°1242810
chrisbk
-
Posté le 10-11-2005 à 00:10:08  profilanswer
 

heuh mais ca compile et ca se lance, ton truc ? [:le kneu]

n°1242813
gocho
Posté le 10-11-2005 à 00:16:41  profilanswer
 

euh j'ai po trop compris le "zou avec truc " ^^
le sock c'est quand j'ai renomme mes variables, j'ai oublie celle la (et je m'etonnais de me taper un segfault quand je terminais....je comprends un peu maintenant :p
Sinon ouais ca se compile et ca se lance (enfin aujourd'hui parce que j'ai fait quelques modifs dessus toute a l'heure et j'ai pas eu le temps de les reporter ici )

n°1242814
chrisbk
-
Posté le 10-11-2005 à 00:17:18  profilanswer
 

bin des "sock" t'en a plein ton programme, donc je m'etonne un peu que ca compile [:el g]

mood
Publicité
Posté le 10-11-2005 à 00:17:18  profilanswer
 

n°1242815
gocho
Posté le 10-11-2005 à 00:18:06  profilanswer
 

et pour les globales vaut mieux que je les declare dans le main et que je les passe en param de chaque fonction ou j'en ai besoin?

n°1242816
gocho
Posté le 10-11-2005 à 00:19:26  profilanswer
 

pour le sock ca depend des fonctions en fait, il me semble que c'etait le seul.
Dans les autres c'est normal (enfin va falloir que je repasse ca au crible : :D : )

n°1242817
chrisbk
-
Posté le 10-11-2005 à 00:19:41  profilanswer
 

bin vu leur tronche, deja je dirais qu'elles iraient bien dans une structure, vu qu'elles servent a decrire une seule et meme chose (un serveur et ses clients), ca te limitera le paquet
 
apres comme t'es en environnement multithread, il faut que tu geres avec attention l'utilisations de ce genre de variable partagée entre plusieurs thread. (utilisation de synchronisation)
 

n°1242818
gocho
Posté le 10-11-2005 à 00:21:56  profilanswer
 

ah...j'pensais bien que ca viendrait la.
Comme j'ai pas encore vraiment bien capte tout ca :  
La synchro c'est comment on la fait? c'est juste empecher deux threads d'acceder a la meme variable en meme temps avec les mutex c'est ca? (j'ai jete un coup d'oeil mais pas encore eu le temps de m'atteler a la tâche)

n°1242819
gocho
Posté le 10-11-2005 à 00:24:44  profilanswer
 

et pour la structure un truc du genre  :  

Code :
  1. struct _serveur{
  2. char nom_serveur[LONGUEUR_MAX];
  3. int nb_clients;
  4. int case_libre;
  5. client tab_clients[MAX_CLIENTS];
  6. };
  7. typedef struct _serveur serveur;

 
ca le fait?

Message cité 1 fois
Message édité par gocho le 10-11-2005 à 00:25:00
n°1242820
chrisbk
-
Posté le 10-11-2005 à 00:24:52  profilanswer
 

gocho a écrit :


La synchro c'est comment on la fait? c'est juste empecher deux threads d'acceder a la meme variable en meme temps avec les mutex c'est ca? (j'ai jete un coup d'oeil mais pas encore eu le temps de m'atteler a la tâche)


 
ouais, par exemple.
 
Si on prends une de tes boucles
 

Code :
  1. for (i=0;i<case_libre;i++){


 
la c'est dangeureux car tu te bases sur une borne qui peut potentiellement varier. Imagine la cas le plus moche,  
 
 
thread 1 : compare i (2) avec case_libre (3)
thread 1: entre dans la boucle (condition valide)
 
thread 2 : decremente case_libre, libere la vieille socket situé en client[2]
 
thread 1 : essaye d'ecrire sur client[2]
 
Blam
 
 
 
 
 
 

n°1242822
chrisbk
-
Posté le 10-11-2005 à 00:25:53  profilanswer
 

gocho a écrit :

et pour la structure un truc du genre  :  

Code :
  1. struct _serveur{
  2. char nom_serveur[LONGUEUR_MAX];
  3. int nb_clients;
  4. int case_libre;
  5. client tab_clients[MAX_CLIENTS];
  6. };
  7. typedef struct _serveur serveur;

 
ca le fait?


 
ouais, un peu bourrin mais disons que tu debutes alors oui :d
 
par contre tu peux t'eviter des lignes
 

Code :
  1. typedef struct _serveur{
  2. client tab_clients[MAX_CLIENTS];
  3. char nom_serveur[LONGUEUR_MAX];
  4. int nb_clients;
  5. int case_libre;
  6. }serveur;


n°1242824
gocho
Posté le 10-11-2005 à 00:26:11  profilanswer
 

ah j'avoue ca va faire un gros bouzin si ca se passe ca...hop poubelle le programme :p

n°1242826
chrisbk
-
Posté le 10-11-2005 à 00:27:19  profilanswer
 

gocho a écrit :

ah j'avoue ca va faire un gros bouzin si ca se passe ca...hop poubelle le programme :p


 
vala. Donc faut proteger au mutex. Ca allourdi le code donc essaye de faire ca proprement
 
(le multithread c'est clairement pas chose facile)

n°1242828
gocho
Posté le 10-11-2005 à 00:28:31  profilanswer
 

oue j'aime bien voir toutes les lignes, l'optimisation des lignes c'est pas mon truc :D
 
Sinon pourquoi bourrin? qu'est ce qu'il y aurait de moins bourrin?(ve apprendre moi :))

n°1242829
chrisbk
-
Posté le 10-11-2005 à 00:29:26  profilanswer
 

gocho a écrit :


Sinon pourquoi bourrin? qu'est ce qu'il y aurait de moins bourrin?(ve apprendre moi :))


 
Bin ce qu'il y a de bourrin c'est le codage direct du nombre de client max et ce genre de truc. Ca fait des gros tableaux dans une structure, c'est pas forcement élegant. une alloc dynamique serait de bon aloy, quoi

Message cité 1 fois
Message édité par chrisbk le 10-11-2005 à 00:29:46
n°1242830
gocho
Posté le 10-11-2005 à 00:30:23  profilanswer
 

ben d'apres ce que j'ai vu sur les mutex ca donnerai un truc dans le style :  
 

Code :
  1. int main(int argc, char*argv[]){
  2. //je declare le mutex
  3. //je mets toutes mes conneries
  4. //je block  
  5. //je touche aux variables sensibles  
  6. //je debloke
  7. }

 
Is it right?

n°1242832
gocho
Posté le 10-11-2005 à 00:31:15  profilanswer
 

chrisbk a écrit :

Bin ce qu'il y a de bourrin c'est le codage direct du nombre de client max et ce genre de truc. Ca fait des gros tableaux dans une structure, c'est pas forcement élegant. une alloc dynamique serait de bon aloy, quoi


 
un p'ti coup de malloc donc...j'vais commencer a bien le gerer celui la a la fin  :lol:
 
edit : attends attends...si je declare mon tableau de client avec un malloc.
il est donc NULL au debut.
Mais si je le remplis, ca veut dire realloc a chaque nouveau client/depart de client ?c'est bien ca ( :cry:  inside)?

Message cité 1 fois
Message édité par gocho le 10-11-2005 à 00:32:50
n°1242833
chrisbk
-
Posté le 10-11-2005 à 00:33:34  profilanswer
 

en gros, mais pas que dans le main hein ? tes fonctions envoi_limite et envoi_general en profiterait bien aussi, par exemple.
 
Y'a de la bonne base, mais y'aurait pas mal de chose a faire sur ton code pour le rendre plus chouette et solide, seulement la chui un peu claqué [:pingouino] Essaye de voir si certaines parties peuvent etre redécoupée en fonction (pour racourcir d'autre fonctions), et betement aussi essaye de sortir le code de main() qui n'a rien a y faire (grosso modo, tout :d) et qui donc serait mieux dans une fonction
 

n°1242835
gocho
Posté le 10-11-2005 à 00:36:13  profilanswer
 

oui oui le mutex quand je disai dans le main ,j'entendai par la dans chaque fonction ou je modifie une variable.
 
comment ca redecoupees? enfin je comprends c'que ca veut dire mais quoi par exemple?
Sinon pour le main en fait je compte laisser au final que de l'appel de fonction, c'est juste que tout ce qui reste n'a pas encore ete fait :D

n°1242836
chrisbk
-
Posté le 10-11-2005 à 00:36:38  profilanswer
 

gocho a écrit :

un p'ti coup de malloc donc...j'vais commencer a bien le gerer celui la a la fin  :lol:
 
edit : attends attends...si je declare mon tableau de client avec un malloc.
il est donc NULL au debut.
Mais si je le remplis, ca veut dire realloc a chaque nouveau client/depart de client ?c'est bien ca ( :cry:  inside)?


 
bon, globalement, je verrais un truc comme ca (vite fait, hein, en me basant sur ton code)

Code :
  1. typedef struct _MonServeur
  2. {
  3.   client * tab_client;
  4.   char * nom_serveur;
  5.   int case_libre;
  6.   int nb_client;
  7. }MonServeur;
  8. MonServeur * CreerServeur(const char *nom, int maxClient)
  9. {
  10.    MonServeur res = malloc(sizeof(struct _MonServeur));
  11.    res->tabClient = malloc(sizeof(client) * maxclient);
  12.    res->case_libre = res->nb_client = 0:
  13.    res->nom_serveur = strdup(nom);
  14.    return res;
  15. }


 
(je torche un brin, pas de test ni rien)
 
et pour la suite des operations tu bosses sur ta structure "MonServeur"
 
 

n°1242837
gocho
Posté le 10-11-2005 à 00:38:27  profilanswer
 

ok.donc du dynamique au maximum...on va essayer hein.
Par contre : a quoi sert le const? je l'ai deja vu mais jamais encore reussi a capter a quoi qu'il sert.

n°1242838
chrisbk
-
Posté le 10-11-2005 à 00:39:17  profilanswer
 

gocho a écrit :

ok.donc du dynamique au maximum...on va essayer hein.
Par contre : a quoi sert le const? je l'ai deja vu mais jamais encore reussi a capter a quoi qu'il sert.


 
 
c'est du "je regarde, mais je touche pas"
 
donc la ca signifie que je prends une chaine en entree, mais que je "m'engage" (avec l'aide du compilo) a ne pas la modifier

n°1242839
gocho
Posté le 10-11-2005 à 00:41:28  profilanswer
 

ok. parametre non modifiable par la fonction donc...
il me semble aussi en avoir deja vu sur la fonction non?
du genre const int machin_truc (arg1, arg2) c'est possible ca?
Et si oui ca sert a quoi?

n°1242840
chrisbk
-
Posté le 10-11-2005 à 00:41:58  profilanswer
 

bin la ca veut dire que tu renvoie un entier const, ce qui est d'une utilité discutable

n°1242841
chrisbk
-
Posté le 10-11-2005 à 00:42:07  profilanswer
 

(bon chu pu la, hein ? :d)

n°1242842
gocho
Posté le 10-11-2005 à 00:43:08  profilanswer
 

ouep c'est clair...enfin c'est pas le sujet : je m'egare.
je sais maintenant comment occuper mon demain aprem' :)
edit : oue pareil moi non plus (bonne nuit inside) et pour ceux qui passent par la n'hesitez pas a poster pour me dire si vous voyez d'autres choses ;)


Message édité par gocho le 10-11-2005 à 00:43:59
n°1242863
Emmanuel D​elahaye
C is a sharp tool
Posté le 10-11-2005 à 07:07:45  profilanswer
 

gocho a écrit :

ah...j'pensais bien que ca viendrait la.
Comme j'ai pas encore vraiment bien capte tout ca :  
La synchro c'est comment on la fait? c'est juste empecher deux threads d'acceder a la meme variable en meme temps avec les mutex c'est ca? (j'ai jete un coup d'oeil mais pas encore eu le temps de m'atteler a la tâche)


 
http://mapage.noos.fr/emdel/pthreads.htm


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
n°1242876
gocho
Posté le 10-11-2005 à 08:45:16  profilanswer
 

ok.donc faut que je vois du cote du mutex en parallele avec le pthread_join pour que ce soit optimal donc.
Plus qu'a faire tout ca maintenant...

n°1244873
gocho
Posté le 13-11-2005 à 22:45:46  profilanswer
 

Re bonsoir.
Alors apres un peu de retard j'ai pu me replonger dans mon petit projet.
j'ai retravaille tout ca pour regler toutes les erreurs que j'avais lors de la compilation mais il en reste une que je comprends pas :  
Quand je compile gcc me renvoie un desagreable : collect2 : ld returned 1 exit status
 
Est ce que quelq'un pourrait me dire ce que ca veut dire (dois je reposter le code?)
merci bien :)

n°1244884
chrisbk
-
Posté le 13-11-2005 à 23:06:37  profilanswer
 

pb de link, poste plutot l'erreur en entier

n°1244889
gocho
Posté le 13-11-2005 à 23:12:09  profilanswer
 

je l'ai poste sur un sujet a part, je me dis que ca pourrait reservir a quelqu'un ;)
http://forum.hardware.fr/hardwaref [...] 0093-1.htm

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  Erreur flagrante? Serveur (sockets + threads)

 

Sujets relatifs
Erreur lors de la creation d'une procedure stockéeserveur php/mysql en prod sur XP Pro ?
erreur dans codeLancer un EXE sur le serveur depuis une page HTTP
erreur insertion gros bloc de texte dans mySQLErreur Segmentation
timestamp foire sur serveur unix.(Apache] Monitorer un serveur Apache?
"unreachable code " d'où provient cette erreur?Urgent : erreur lors de la création d'une table.
Plus de sujets relatifs à : Erreur flagrante? Serveur (sockets + threads)


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR