fermeture d'une socket par le distant

fermeture d'une socket par le distant - C - Programmation

Marsh Posté le 24-10-2006 à 15:04:46    

Bonjour a tous(tes),
Comment fait on pour savoir que le distant a cloture une socket?
Exp: Un programme client se connecte a un serveur le dialogue s'etablit il y a des echanges et le serveur decide de cloturer la communication pour une raison ou une autre.
Comment fait le cote client pour se rendre compte que la connection est cloturee de l'autre cote avant de se lancer dans une ecriture sur la socket qui n'aboutirai pas?

Reply

Marsh Posté le 24-10-2006 à 15:04:46   

Reply

Marsh Posté le 24-10-2006 à 15:37:07    

Si tu as un select qui traine dans un coin pour voir l'état de ta chaussette, il te retournera quelque chose t'indiquant que la connexion a fermée...
 
(désolé je n'arrive plus à remettre la main sur mon petit exemple...)

Reply

Marsh Posté le 24-10-2006 à 15:46:47    

Je croyais que select() me renvoyait les descripteur qui avait reçu des donnees et retirait les autres de l'ensemble mais si le distant ferme la socket cela suppose qu'il envoie quelque chose ou que l'etat de la socket change.

Reply

Marsh Posté le 24-10-2006 à 15:51:20    

Arf, finalement ce que je faisais c'était d'attendre un changement pour la disponibilité de données sur le descripteur de fichier

Code :
  1. rVal = select( 0, &fss, null, null, &tv );

avec fss ne "contenant" que le descripteur de ma chaussette, puis

Code :
  1. switch (rVal) {
  2. case 1:
  3.    char buffer[10];
  4.    rVal = recv( buffer, 10, MSG_PEEK );
  5.    if( rVal == 0 ) {
  6.       // déconnexion détectée
  7.    }
  8.    break;
  9. ...
  10. }

Reply

Marsh Posté le 24-10-2006 à 16:11:26    

Oui ça je connais mais comment detecter que le distant a coupe la com pour la couper a mon tour.
Peut on consulter une varriable d'etat sur le descripteur pour verifier qu'il est encore en etat.?

Reply

Marsh Posté le 24-10-2006 à 16:36:46    

Euh... là je ne peux t'aider ...

Reply

Marsh Posté le 24-10-2006 à 16:59:53    

Merci tout de meme.
Si quelqu'un a une solution je reviendrai voir.
A+

Reply

Marsh Posté le 26-10-2006 à 15:32:03    

Je crois que quand le client -par exemple- est fermé proprement, les fonctions du serveur tel que recv() et send() retourne la valeur 0 .
Mais je ne suis pas très sure de moi.


Message édité par Bad_Day le 26-10-2006 à 15:32:30
Reply

Marsh Posté le 29-10-2006 à 06:45:04    

C'est presque ça.
Lorsque le distant ferme sa socket un caractere EOF est enoye pour indiquer la fermeture de la socket.
Ce que je ne sais pas encore c'est si c'est le systeme qui envoie ce caractere de lui meme ou si c'est au programmeur de l'envoyer avant de fermer la socket utilisee.

Reply

Marsh Posté le 29-10-2006 à 16:56:05    

yartempion a écrit :

Ce que je ne sais pas encore c'est si c'est le systeme qui envoie ce caractere de lui meme ou si c'est au programmeur de l'envoyer avant de fermer la socket utilisee.


Ni l'un ni l'autre,
C'est a toi de tester ce que retourne tes fonctions ( dans ton client (par exemple) ), pour savoir si le serveur distant a été fermé ou pas.
 

Reply

Marsh Posté le 29-10-2006 à 16:56:05   

Reply

Marsh Posté le 30-10-2006 à 15:02:06    

Bad_Day a écrit :

Ni l'un ni l'autre,
C'est a toi de tester ce que retourne tes fonctions ( dans ton client (par exemple) ), pour savoir si le serveur distant a été fermé ou pas.


Bonjour,
Qu'est ce que je dois tester quelle fonction?
La socket est un descripteur et c'est moi qui decide quand le ferme.
Les fonctoin read write impossible puisque j'utilise select() donc tant qu'il n'y a rien d'arrive inutile de tester.
Je ne vois pas trop quoi tester si tu peux me mettre sur la voie .
Merci

Reply

Marsh Posté le 30-10-2006 à 16:02:55    

Excuse-moi, mais le bout de code que j'ai indiqué plus haut fonctionne très bien.
 
Dans le cas précisé, le select retourne bien 1 quand il y a un changement d'état de la connexion. Ensuite, le recv avec MSG_PEEK pour ne pas enlever les données du buffer et surtout tester la valeur de retour de recv te permet de déterminer si la connexion est rompue (valeur de retour 0) sinon tu peux faire ton recv standard en récupérant les données du buffer.

Reply

Marsh Posté le 30-10-2006 à 16:47:34    

bb138 a écrit :

Ensuite, le recv avec MSG_PEEK pour ne pas enlever les données du buffer et surtout tester la valeur de retour de recv te permet de déterminer si la connexion est rompue (valeur de retour 0) sinon tu peux faire ton recv standard en récupérant les données du buffer.


 
C'est ce que je disais non ?
 

Reply

Marsh Posté le 30-10-2006 à 17:51:08    

Je ne comprendspas trop.
select() renvoie le nombre de descripteurs qui ontsubits des modificationsdes condition fixees (ensemble de descripteurs prets en lectures dans ce cas) puis efface tous les descripteur qui ne repondent pas aux condition  dans l'ensemble concerne.
J'ai essaye amis comme on laisse les donnees on boucle en lecture sur la socket je te faits parvenir le code entier.
 

Reply

Marsh Posté le 30-10-2006 à 18:10:11    

#include<stdio.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<netdb.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<termios.h>
#include<sys/time.h>
#include<stdlib.h>
#include<fcntl.h>
#define LG_BUFFER=1
 
/*lancement des options de session*/
LANCEMENT (socket1)
{
}
 
 
/*procedure de negociation d'option telnet*/
NEGOCIATION (mess_nego1,socket1)
{
unsigned char *mess_nego11,*rep_mess_nego1;
/*int socket1;*/
 
rep_mess_nego1=mess_nego11=mess_nego1;
printf("\nN° traitement des  types de message %d  %d %d valeur de la socket %d",*mess_nego11,*(mess_nego11+1),*(mess_nego11+2),socket1);
switch(*(mess_nego11+1))
{
case 250: printf("\nSB %d demande de sous negociation",*(mess_nego11+1));
case 251: printf("\nWILL %d demande de negociation",*(mess_nego11+1));
 OPTION_NEGOCIEE(mess_nego11,socket);
 break;
case 252: printf("\nWONT %d refus de negociation",*(mess_nego11+1));
 *(rep_mess_nego1+1)=254;
 write(socket1,rep_mess_nego1,3);
 printf("\nReponse a WONT = %d",*(rep_mess_nego1+1));
 break;
case 253: printf("\nDO %d demande de negociation",*(mess_nego11+1));
 OPTION_NEGOCIEE(mess_nego11,socket);
 break;
case 254: printf("\nDONT %d refus de negociation",*(mess_nego11+1));
 *(rep_mess_nego1+1)=252;
 write(socket1,rep_mess_nego1,3);
 printf("\nReponse a WONT = %d",*(rep_mess_nego1+1));
 break;
default: printf("\nErreur de traitement sur neociation N° option %d",*(mess_nego11+1));
 break;
}
 
}
 
 
/*N° d'option a negocier*/
OPTION_NEGOCIEE(mess_nego11,socket)
{
printf("\nprocedure de negociation d'option" );
printf("\nVerification de l'option a negocier" );
}
 
/*DEBUT DE LA ROUTINE PRINCIPALE*/
main(argc,argv)
int argc;
char **argv;
{/*Debut du main*/
 
unsigned char *buffer_RX,*buffer_TX;
unsigned char *mess_nego;
int socket1,deblocage,connection,nb_lu,nb_ec,i,j,k,flag_nego_option;
struct sockaddr_in addr_distant;
struct servent *service_distant;
struct termios term_initial,term_com,sock_ini,sock_com;
struct timeval delai;
fd_set set;
flag_nego_option=0;
 
/*Preparation des parametres de  connection*/
printf("\nadresse %s",argv[1]);
service_distant=getservbyname("telnet","tcp" );
memset(&addr_distant,0,sizeof(struct sockaddr_in));
addr_distant.sin_family=PF_INET;
addr_distant.sin_port=htons(service_distant->s_port);
if((inet_aton(argv[1],&addr_distant.sin_addr.s_addr))==0)
printf("\nimpossible de remplir le  champ s_addr" );
printf("\nvaleur apres inet_aton() \t%08X",ntohl(addr_distant.sin_addr.s_addr));
printf("\nDEBUT DE PROGRAMME" );
printf("\ncration de la socket" );
 
/*Creation du point de communicatio*/
if((socket1=socket(AF_INET,SOCK_STREAM,0))<0)
printf("\nCreation de socket echouee" );
printf("\nNumero de socket \t%d",socket1);
printf("\nDeblocage de la socket" );
if((fcntl(socket1,F_SETFL,O_NONBLOCK))<0)
printf("\nProbleme sur fcntl" );
printf("\naddr_distant.sin_family \t%d",addr_distant.sin_family);
printf("\naddr_distant.sin_port\t%d",addr_distant.sin_port);
printf("\naddr_distant.sin_addr.s_addr\t%s\n",inet_ntoa(addr_distant.sin_addr.s_addr));
 
 
 
/*Procedure de mis en place du mode non bloquant sur stdin*/
tcgetattr(STDIN_FILENO,&term_initial);
tcgetattr(STDIN_FILENO,&term_com);
term_com.c_iflag &=ICRNL;
term_com.c_lflag &=~ICANON;/*,ECHONL,ICANON,IEXTEN);*/
term_com.c_lflag &=~ECHO;
term_com.c_cc[VTIME]=0;
term_com.c_cc[VMIN]=0;
if(tcsetattr(STDIN_FILENO,TCSANOW,&term_com)!=0)
printf("\ntransformation du terminal echoue" );
tcgetattr(socket1,&sock_ini);
tcgetattr(socket1,&sock_com);
sock_com.c_iflag |=OCRNL;
sock_com.c_oflag &=OPOST;
if(tcsetattr(socket1,TCSANOW,&sock_com)!=0)
printf("\ntransformation du terminal socket1 echoue" );
printf("\ncaracteres attendus %c %c %c",255,24,250);
 
/*Connection au point distant*/
printf("\ntentative de connection %d",connection=0);
if((connection=connect(socket1,(struct sockaddr*)&addr_distant,sizeof(addr_distant)))>0)
printf("\nvaleur de retour apres connect %d\n",connection);
else printf("\nconnection OK=%d",connection);
 
/*Modification des delaie pour passer en mode non bloquant*/
delai.tv_sec=0;
delai.tv_usec=0;
while(1)
{/*Debut du while 1*/
 
/*Initialisation de l'ensemble des descripteurs a multiplexer*/
FD_ZERO (&set);
FD_SET (socket1,&set);
FD_SET (STDIN_FILENO,&set);
 
/*Selection de l'ensemble des descripteurs a multiplexer en reception*/
if(select(socket1+1,&set,&set,NULL,&delai)<0)
break;
      if(FD_ISSET(STDIN_FILENO,&set))
       
 {/*Debut du if*/
 /*Initialisation d un bloc memoire pour un caractere*/
 if((buffer_RX=(char*) calloc (LG_BUFFER,sizeof (char)))==NULL)
 printf("\nImpossible d'allouer la memoire buffer_RX STDIN_FILENO" );
 nb_lu=0;
 if((nb_lu=read(STDIN_FILENO,buffer_RX,LG_BUFFER))<0)
 printf("\nerreur sur lecture d'entree ou rien a ecrire retour de nb_lu %d",nb_lu);
 if(buffer_RX[nb_lu-1]==10)
 {
 buffer_RX=realloc(buffer_RX,LG_BUFFER+2,sizeof(char));
 buffer_RX[nb_lu-1]=13;
 buffer_RX[nb_lu]=10;
 printf("\nles codes envoyes sont %d %d nb_lu=%d\n",buffer_RX[0],buffer_RX[1],nb_lu);
 nb_lu=nb_lu+1;
 }
 nb_ec=write(socket1,buffer_RX,nb_lu);
 free(buffer_RX);
 }/*Fin du if*/
 
 
/*On teste l'arrivee de donnees sur la socket1*/
 if(FD_ISSET(socket1,&set))
 
 {/*Debut du if*/
 if((buffer_RX=(unsigned char*) calloc (LG_BUFFER,sizeof (unsigned char)))==NULL)
 printf("\nImpossible d'allouer la memoire buffer_RX pour socket1" );
  nb_lu=0;
  i=0;
  while((nb_lu=recv(socket1,buffer_RX,LG_BUFFER,MSG_PEEK))>0)
  {/*Debut du while*/
  if(nb_lu==0)
  printf("\nCaractere NULL recu = %d",buffer_RX[0]);
 if(buffer_RX[0]==255)
  {/*Un caractere IAC est arrive*/
  i=1;
  if((mess_nego=(unsigned char*) calloc (i,sizeof (unsigned char)))==NULL)
  printf("\nErreur sur attribution memoire mess_nego" );
  flag_nego_option=1;
  *mess_nego=*buffer_RX;
  mess_nego=%d buffer_RX=%d",*mess_nego,*buffer_RX,mess_nego,buffer_RX);*/
  while(flag_nego_option==1)
  {/*debut du while*/
  if((mess_nego=realloc(mess_nego,(i+1)*sizeof(unsigned char)))==NULL)
  printf("\nErreur sur attribution memoire" );
  nb_lu=read(socket1,mess_nego+i,LG_BUFFER);
  if(*(mess_nego+i)>=236 && *(mess_nego+i)<255)
  { /*Phase de test 250>IAC<255*/
  printf("\non passe le if de *mess_nego valeur *mess_nego+i = %d et *mess_nego = %d ",*(mess_nego+i),*(mess_nego));
  ++i;
  if((mess_nego=realloc(mess_nego,(i+1)*sizeof(unsigned char)))==NULL)
  printf("\nErreur sur attribution memoire" );
  nb_lu=read(socket1,mess_nego+i,LG_BUFFER);
  printf ("\nvaleur de i = %d",i);
  printf("\nnouveau mess_nego = " );
  for(j=0;j<=i;j++)
  printf(" j= %d %d",j,*(mess_nego+j));
  printf("\nValeur transmise a OPTION_NEGOCIEE %d  %d",mess_nego,*mess_nego,*(mess_nego+1));
  NEGOCIATION(mess_nego,socket1);
  }
  flag_nego_option=0;
  free(mess_nego);
  printf("\nle free(mes_nego) est ok valeur de l'adresse mess_nego %d %d\n",mess_nego,*mess_nego);
  memset(mess_nego,0,strlen(mess_nego));
  ++i;
  } /*fin de while(flag_nego_option)*/
  printf("\nfin du if(buffer_RX[0]==255)" );
       
  } /*fin de if(buffer_RX[0]==255)*/
     
     
  else
  {/*Debut du else*/
  write(STDOUT_FILENO,buffer_RX,nb_lu);
  } /*Fin du else*/
  nb_lu=0;
  }/*fin du while*/
  free(buffer_RX);
  memset(buffer_RX,0,strlen(buffer_RX));
   
 }/*Fin du if*/
}/*Fin du while 1*/
 /*printf("\n" );*/
printf("\nSortie de boucle avec ou sans raison nb_lu = %d",nb_lu);
close(socket1);
if((tcsetattr(STDIN_FILENO,TCSANOW,&term_initial))!=0)
printf("\nremeise en etat du stdin echoue\n" );
if((tcsetattr(socket1,TCSANOW,&sock_ini))!=0)
printf("\nremeise en etat du stdin echoue\n" );
printf ("\nSortie du prog\n" );
 
}/*fin du main*/
 

Reply

Marsh Posté le 30-10-2006 à 18:33:02    

yartempion a écrit :

#include<stdio.h>
#include<sys/socket.h>


Tu n'es pas nouveau ici. Tu n'as jamais entendu parlé des balises code, ou tu cherches à affirmer ton coté rebelle ?
 
http://maudoune.free.fr/dotclear/images/rebelle.jpg


Message édité par Emmanuel Delahaye le 30-10-2006 à 18:34:50

---------------
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/
Reply

Marsh Posté le 30-10-2006 à 19:08:37    

Excusez j'ai oublie.

Code :
  1. #include<stdio.h>
  2. #include<sys/socket.h>
  3. #include<sys/types.h>
  4. #include<netinet/in.h>
  5. #include<netdb.h>
  6. #include<arpa/inet.h>
  7. #include<unistd.h>
  8. #include<termios.h>
  9. #include<sys/time.h>
  10. #include<stdlib.h>
  11. #include<fcntl.h>
  12. #define LG_BUFFER=1
  13. /*lancement des options de session*/
  14. LANCEMENT (socket1)
  15. {
  16. }
  17. /*procedure de negociation d'option telnet*/
  18. NEGOCIATION (mess_nego1,socket1)
  19. {
  20. unsigned char *mess_nego11,*rep_mess_nego1;
  21. /*int socket1;*/
  22. rep_mess_nego1=mess_nego11=mess_nego1;
  23. printf("\nN° traitement des  types de message %d  %d %d valeur de la socket %d",*mess_nego11,*(mess_nego11+1),*(mess_nego11+2),socket1);
  24. switch(*(mess_nego11+1))
  25. {
  26. case 250: printf("\nSB %d demande de sous negociation",*(mess_nego11+1));
  27. case 251: printf("\nWILL %d demande de negociation",*(mess_nego11+1));
  28. OPTION_NEGOCIEE(mess_nego11,socket);
  29. break;
  30. case 252: printf("\nWONT %d refus de negociation",*(mess_nego11+1));
  31. *(rep_mess_nego1+1)=254;
  32. write(socket1,rep_mess_nego1,3);
  33. printf("\nReponse a WONT = %d",*(rep_mess_nego1+1));
  34. break;
  35. case 253: printf("\nDO %d demande de negociation",*(mess_nego11+1));
  36. OPTION_NEGOCIEE(mess_nego11,socket);
  37. break;
  38. case 254: printf("\nDONT %d refus de negociation",*(mess_nego11+1));
  39. *(rep_mess_nego1+1)=252;
  40. write(socket1,rep_mess_nego1,3);
  41. printf("\nReponse a WONT = %d",*(rep_mess_nego1+1));
  42. break;
  43. default: printf("\nErreur de traitement sur neociation N° option %d",*(mess_nego11+1));
  44. break;
  45. }
  46. }
  47. /*N° d'option a negocier*/
  48. OPTION_NEGOCIEE(mess_nego11,socket)
  49. {
  50. printf("\nprocedure de negociation d'option" );
  51. printf("\nVerification de l'option a negocier" );
  52. }
  53. /*DEBUT DE LA ROUTINE PRINCIPALE*/
  54. main(argc,argv)
  55. int argc;
  56. char **argv;
  57. {/*Debut du main*/
  58. unsigned char *buffer_RX,*buffer_TX;
  59. unsigned char *mess_nego;
  60. int socket1,deblocage,connection,nb_lu,nb_ec,i,j,k,flag_nego_option;
  61. struct sockaddr_in addr_distant;
  62. struct servent *service_distant;
  63. struct termios term_initial,term_com,sock_ini,sock_com;
  64. struct timeval delai;
  65. fd_set set;
  66. flag_nego_option=0;
  67. /*Preparation des parametres de  connection*/
  68. printf("\nadresse %s",argv[1]);
  69. service_distant=getservbyname("telnet","tcp" );
  70. memset(&addr_distant,0,sizeof(struct sockaddr_in));
  71. addr_distant.sin_family=PF_INET;
  72. addr_distant.sin_port=htons(service_distant->s_port);
  73. if((inet_aton(argv[1],&addr_distant.sin_addr.s_addr))==0)
  74. printf("\nimpossible de remplir le  champ s_addr" );
  75. printf("\nvaleur apres inet_aton() \t%08X",ntohl(addr_distant.sin_addr.s_addr));
  76. printf("\nDEBUT DE PROGRAMME" );
  77. printf("\ncration de la socket" );
  78. /*Creation du point de communicatio*/
  79. if((socket1=socket(AF_INET,SOCK_STREAM,0))<0)
  80. printf("\nCreation de socket echouee" );
  81. printf("\nNumero de socket \t%d",socket1);
  82. printf("\nDeblocage de la socket" );
  83. if((fcntl(socket1,F_SETFL,O_NONBLOCK))<0)
  84. printf("\nProbleme sur fcntl" );
  85. printf("\naddr_distant.sin_family \t%d",addr_distant.sin_family);
  86. printf("\naddr_distant.sin_port\t%d",addr_distant.sin_port);
  87. printf("\naddr_distant.sin_addr.s_addr\t%s\n",inet_ntoa(addr_distant.sin_addr.s_addr));
  88. /*Procedure de mis en place du mode non bloquant sur stdin*/
  89. tcgetattr(STDIN_FILENO,&term_initial);
  90. tcgetattr(STDIN_FILENO,&term_com);
  91. term_com.c_iflag &=ICRNL;
  92. term_com.c_lflag &=~ICANON;/*,ECHONL,ICANON,IEXTEN);*/
  93. term_com.c_lflag &=~ECHO;
  94. term_com.c_cc[VTIME]=0;
  95. term_com.c_cc[VMIN]=0;
  96. if(tcsetattr(STDIN_FILENO,TCSANOW,&term_com)!=0)
  97. printf("\ntransformation du terminal echoue" );
  98. tcgetattr(socket1,&sock_ini);
  99. tcgetattr(socket1,&sock_com);
  100. sock_com.c_iflag |=OCRNL;
  101. sock_com.c_oflag &=OPOST;
  102. if(tcsetattr(socket1,TCSANOW,&sock_com)!=0)
  103. printf("\ntransformation du terminal socket1 echoue" );
  104. printf("\ncaracteres attendus %c %c %c",255,24,250);
  105. /*Connection au point distant*/
  106. printf("\ntentative de connection %d",connection=0);
  107. if((connection=connect(socket1,(struct sockaddr*)&addr_distant,sizeof(addr_distant)))>0)
  108. printf("\nvaleur de retour apres connect %d\n",connection);
  109. else printf("\nconnection OK=%d",connection);
  110. /*Modification des delaie pour passer en mode non bloquant*/
  111. delai.tv_sec=0;
  112. delai.tv_usec=0;
  113. while(1)
  114. {/*Debut du while 1*/
  115. /*Initialisation de l'ensemble des descripteurs a multiplexer*/
  116. FD_ZERO (&set);
  117. FD_SET (socket1,&set);
  118. FD_SET (STDIN_FILENO,&set);
  119. /*Selection de l'ensemble des descripteurs a multiplexer en reception*/
  120. if(select(socket1+1,&set,&set,NULL,&delai)<0)
  121. break;
  122.       if(FD_ISSET(STDIN_FILENO,&set))
  123.      
  124. {/*Debut du if*/
  125. /*Initialisation d un bloc memoire pour un caractere*/
  126. if((buffer_RX=(char*) calloc (LG_BUFFER,sizeof (char)))==NULL)
  127. printf("\nImpossible d'allouer la memoire buffer_RX STDIN_FILENO" );
  128. nb_lu=0;
  129. if((nb_lu=read(STDIN_FILENO,buffer_RX,LG_BUFFER))<0)
  130. printf("\nerreur sur lecture d'entree ou rien a ecrire retour de nb_lu %d",nb_lu);
  131. if(buffer_RX[nb_lu-1]==10)
  132. {
  133. buffer_RX=realloc(buffer_RX,LG_BUFFER+2,sizeof(char));
  134. buffer_RX[nb_lu-1]=13;
  135. buffer_RX[nb_lu]=10;
  136. printf("\nles codes envoyes sont %d %d nb_lu=%d\n",buffer_RX[0],buffer_RX[1],nb_lu);
  137. nb_lu=nb_lu+1;
  138. }
  139. nb_ec=write(socket1,buffer_RX,nb_lu);
  140. free(buffer_RX);
  141. }/*Fin du if*/
  142.  
  143.  
  144. /*On teste l'arrivee de donnees sur la socket1*/
  145. if(FD_ISSET(socket1,&set)) 
  146. {/*Debut du if*/
  147. if((buffer_RX=(unsigned char*) calloc (LG_BUFFER,sizeof (unsigned char)))==NULL)
  148. printf("\nImpossible d'allouer la memoire buffer_RX pour socket1" );
  149.   nb_lu=0;
  150.   i=0;
  151.   while((nb_lu=recv(socket1,buffer_RX,LG_BUFFER,MSG_PEEK))>0)
  152.   {/*Debut du while*/
  153.   if(nb_lu==0)
  154.   printf("\nCaractere NULL recu = %d",buffer_RX[0]);  if(buffer_RX[0]==255)
  155.   {/*Un caractere IAC est arrive*/
  156.   i=1;
  157.   if((mess_nego=(unsigned char*) calloc (i,sizeof (unsigned char)))==NULL)
  158.   printf("\nErreur sur attribution memoire mess_nego" );
  159.   flag_nego_option=1;
  160.   *mess_nego=*buffer_RX;
  161.   mess_nego=%d buffer_RX=%d",*mess_nego,*buffer_RX,mess_nego,buffer_RX);*/
  162.   while(flag_nego_option==1)
  163.   {/*debut du while*/
  164.   if((mess_nego=realloc(mess_nego,(i+1)*sizeof(unsigned char)))==NULL)
  165.   printf("\nErreur sur attribution memoire" );
  166.   nb_lu=read(socket1,mess_nego+i,LG_BUFFER);
  167.   if(*(mess_nego+i)>=236 && *(mess_nego+i)<255)
  168.   { /*Phase de test 250>IAC<255*/
  169.   printf("\non passe le if de *mess_nego valeur *mess_nego+i = %d et *mess_nego = %d ",*(mess_nego+i),*(mess_nego));
  170.   ++i;
  171.   if((mess_nego=realloc(mess_nego,(i+1)*sizeof(unsigned char)))==NULL)
  172.   printf("\nErreur sur attribution memoire" );
  173.   nb_lu=read(socket1,mess_nego+i,LG_BUFFER);
  174.   printf ("\nvaleur de i = %d",i);
  175.   printf("\nnouveau mess_nego = " );
  176.   for(j=0;j<=i;j++)
  177.   printf(" j= %d %d",j,*(mess_nego+j));
  178.   printf("\nValeur transmise a OPTION_NEGOCIEE %d  %d",mess_nego,*mess_nego,*(mess_nego+1));
  179.   NEGOCIATION(mess_nego,socket1);
  180.   }
  181.   flag_nego_option=0;
  182.   free(mess_nego);
  183.   printf("\nle free(mes_nego) est ok valeur de l'adresse mess_nego %d %d\n",mess_nego,*mess_nego);
  184.   memset(mess_nego,0,strlen(mess_nego));
  185.   ++i;
  186.   } /*fin de while(flag_nego_option)*/
  187.   printf("\nfin du if(buffer_RX[0]==255)" );
  188.      
  189.   } /*fin de if(buffer_RX[0]==255)*/
  190.    
  191.    
  192.   else
  193.   {/*Debut du else*/
  194.   write(STDOUT_FILENO,buffer_RX,nb_lu);
  195.   } /*Fin du else*/
  196.   nb_lu=0;
  197.   }/*fin du while*/
  198.   free(buffer_RX);
  199.   memset(buffer_RX,0,strlen(buffer_RX));
  200.  
  201. }/*Fin du if*/
  202. }/*Fin du while 1*/
  203. /*printf("\n" );*/
  204. printf("\nSortie de boucle avec ou sans raison nb_lu = %d",nb_lu);
  205. close(socket1);
  206. if((tcsetattr(STDIN_FILENO,TCSANOW,&term_initial))!=0)
  207. printf("\nremeise en etat du stdin echoue\n" );
  208. if((tcsetattr(socket1,TCSANOW,&sock_ini))!=0)
  209. printf("\nremeise en etat du stdin echoue\n" );
  210. printf ("\nSortie du prog\n" );
  211. }/*fin du main*/


C'est fait

Reply

Marsh Posté le 30-10-2006 à 21:37:21    

yartempion a écrit :

Excusez j'ai oublie.


Et tu ne penses pas qu'il suffisait de modifier ton post original ?
Tu n'as donc jamais utilisé ce bouton :  http://forum-images.hardware.fr/themes_static/images_forum/1/edit.gif ?


Message édité par Emmanuel Delahaye le 30-10-2006 à 21:38:28

---------------
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/
Reply

Marsh Posté le 31-10-2006 à 09:28:34    

Bad_Day > Si tu as absolument raison mais comme il ne semblait pas avoir tenu compte de ce que j'avais dit initialement après le post de ton message, je me suis dit qu'une piqûre de rappel était nécessaire :D
 
yartempion > je n'ai pas tout regardé en détail, mais tu ne passe pas par ton

Code :
  1. if(nb_lu==0)

lors d'une déconnexion ?


Message édité par bb138 le 31-10-2006 à 09:40:13
Reply

Marsh Posté le 31-10-2006 à 13:28:35    

En effet une fois la socket fermee par le distant c'est bien comme tu l'avais dit on arrive a lire la socket mais le retour de read ou de recv est = 0 par contre il ne faut pas utiliser le MSG_PEEK car on ne retire pas les donees du buffer et on vient lire constamment les memes donnes on entre dans une boucleinfinie en ce qui concerne mon code.
Merci A+

Reply

Marsh Posté le 31-10-2006 à 19:04:06    

Le pb de la detection de fermeture de la socket est regle mais j'ai observe un phenomene  bizzare surconnect().
Selon que je me connecte a un routeur ou un serveur jen'ai pas le meme code retour en cas de reussite un coup j'ai -1 un autre 0.
Pourquoi cette difference?

Reply

Marsh Posté le 02-11-2006 à 09:47:59    

S'il retourne -1 c'est qu'il y a un echec de connexion... (cf. man)

Reply

Marsh Posté le 06-11-2006 à 15:19:42    

Bonjour a tous,
J'ai pousse mes investigations plus loin.
Je recupere bien -1 au retour de connect() et je suis alle lire la valeur de errno qui se trouve etre a 245 et qui est Operation now in progress.
Quelqu'un pourrait'il m'expliquer comment traiter cette situation.

Reply

Marsh Posté le 06-11-2006 à 15:30:04    

J'ai pas tout lu, mais, perso, je fonctionne comme ca pour detecter que le client s'en est allé :
lorsque mon select se debloque et qu'un fd est près en lecture, je lis ; normal ; mais je fais le test de la longueur avec <= 0, si c'est vrai, je ferme, sinon, je fais mon traitement habituel.
 
Je n'ai jamais eut de souci de cette manière
 
Concernant le problème avec connect, je n'en ai jamais eut
car je n'ai pas encore codé de client :-) mais des serveurs


Message édité par nORKy le 06-11-2006 à 15:30:30
Reply

Marsh Posté le 07-11-2006 à 09:21:06    

yartempion a écrit :


Je recupere bien -1 au retour de connect() et je suis alle lire la valeur de errno qui se trouve etre a 245 et qui est Operation now in progress.


 
Peut-être que tu as configuré cette socket en non-bloquant ?
Auquel cas il faut un select pour "confirmer" la connection il me semble.
 

Reply

Marsh Posté le 07-11-2006 à 12:50:05    

Bonjour,
J'ai fini par comprendre pourquoi j'avais -1 en faisant afficher la valeur de errno.
Quand la caonnexion se lance errno se positionne  
-a 245 qui est  Operation now in progress
-puis a 244 qui est Operation already in progress
-et enfin a 234 qui est Socket is already connected
Donc le -1 me semble normal puisque la valeur de errno se positionne a chaque fois. Le retour de connecte  a -1 n'est pas totalement pertinent il faut analyser errno a chaque fois et comprendre chaque erreur.

Reply

Marsh Posté le 07-11-2006 à 13:12:33    

:heink:

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed