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

  FORUM HardWare.fr
  Programmation
  C

  fermeture d'une socket par le distant

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

fermeture d'une socket par le distant

n°1464101
yartempion
Posté le 24-10-2006 à 15:04:46  profilanswer
 

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?

mood
Publicité
Posté le 24-10-2006 à 15:04:46  profilanswer
 

n°1464152
bb138
La vie est belle ...
Posté le 24-10-2006 à 15:37:07  profilanswer
 

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...)

n°1464177
yartempion
Posté le 24-10-2006 à 15:46:47  profilanswer
 

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.

n°1464187
bb138
La vie est belle ...
Posté le 24-10-2006 à 15:51:20  profilanswer
 

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. }

n°1464242
yartempion
Posté le 24-10-2006 à 16:11:26  profilanswer
 

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.?

n°1464279
bb138
La vie est belle ...
Posté le 24-10-2006 à 16:36:46  profilanswer
 

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

n°1464302
yartempion
Posté le 24-10-2006 à 16:59:53  profilanswer
 

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

n°1465507
Bad_Day
Posté le 26-10-2006 à 15:32:03  profilanswer
 

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
n°1466741
yartempion
Posté le 29-10-2006 à 06:45:04  profilanswer
 

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.

n°1466993
Bad_Day
Posté le 29-10-2006 à 16:56:05  profilanswer
 

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.
 

mood
Publicité
Posté le 29-10-2006 à 16:56:05  profilanswer
 

n°1467502
yartempion
Posté le 30-10-2006 à 15:02:06  profilanswer
 

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

n°1467547
bb138
La vie est belle ...
Posté le 30-10-2006 à 16:02:55  profilanswer
 

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.

n°1467626
Bad_Day
Posté le 30-10-2006 à 16:47:34  profilanswer
 

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 ?
 

n°1467722
yartempion
Posté le 30-10-2006 à 17:51:08  profilanswer
 

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.
 

n°1467734
yartempion
Posté le 30-10-2006 à 18:10:11  profilanswer
 

#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*/
 

n°1467748
Emmanuel D​elahaye
C is a sharp tool
Posté le 30-10-2006 à 18:33:02  profilanswer
 

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/
n°1467762
yartempion
Posté le 30-10-2006 à 19:08:37  profilanswer
 

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

n°1467822
Emmanuel D​elahaye
C is a sharp tool
Posté le 30-10-2006 à 21:37:21  profilanswer
 

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/
n°1467947
bb138
La vie est belle ...
Posté le 31-10-2006 à 09:28:34  profilanswer
 

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
n°1468154
yartempion
Posté le 31-10-2006 à 13:28:35  profilanswer
 

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+

n°1468437
yartempion
Posté le 31-10-2006 à 19:04:06  profilanswer
 

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?

n°1469030
bb138
La vie est belle ...
Posté le 02-11-2006 à 09:47:59  profilanswer
 

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

n°1471135
yartempion
Posté le 06-11-2006 à 15:19:42  profilanswer
 

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.

n°1471139
nORKy
Grmmph...
Posté le 06-11-2006 à 15:30:04  profilanswer
 

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
n°1471454
cricri_
Posté le 07-11-2006 à 09:21:06  profilanswer
 

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.
 

n°1471564
yartempion
Posté le 07-11-2006 à 12:50:05  profilanswer
 

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.

n°1471574
bb138
La vie est belle ...
Posté le 07-11-2006 à 13:12:33  profilanswer
 

:heink:

mood
Publicité
Posté le   profilanswer
 


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

  fermeture d'une socket par le distant

 

Sujets relatifs
Déactiver la croix de fermeture windowsPb sur lecture de socket
[socket] echange de messages entre client et serveur....Socket, problème à l'écriture.
[C#] Mon application bloque la fermeture de Windows[Telnet] Envoi de la commande Ctrl+c pour stopper le prog distant?
Résolu [Javascript] Agir dans Popup après fermeture de la fenetre mèreLire un fichier distant avec SSH
Convertir un buffer recu par socket pour afficher un entierProbleme de socket ? ou de mise en place dans un fichier ?
Plus de sujets relatifs à : fermeture d'une socket par le distant


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