Pb sur lecture de socket

Pb sur lecture de socket - C - Programmation

Marsh Posté le 10-10-2006 à 12:22:32    

Bonjour,
Voici un code .
Je me trouve bloque pour rendre la socket non bloquante.
Au debut tout ce passe bien je me connecte a un equipement je lis tout ce qui arrive sur la socket.
Mais lorsque il n'y a plus rien qui arrive l'appel read reste en attente pendant un certain temp
et ensuite on boucle indefiniment mais sans arriver a lire l'entree standart.
Est il necessaire de rendre la lecture d'une socket non bloquante.
 
 

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. #define LG_BUFFER=1
  12. /*procedure de negociation d'option telnet*/
  13. OPTION_NEGOCIEE (message_nego)
  14. {
  15. /*char *message_nego;*/
  16. printf("\nN° d'option %d",message_nego);
  17. }
  18. main(argc,argv)
  19. int argc;
  20. char **argv;
  21. {/*Debut du main*/
  22. unsigned char *buffer_RX,*buffer_TX;
  23. unsigned char *mess_nego;
  24. int socket1,connection,nb_lu,nb_ec,i,j,flag_nego_option;
  25. struct sockaddr_in addr_distant;
  26. struct servent *service_distant;
  27. struct termios term_initial,term_com;
  28. struct timeval delai;
  29. fd_set set;
  30. flag_nego_option=0;
  31. /*Preparation des parametres de  connection*/
  32. printf("\nadresse %s",argv[1]);
  33. service_distant=getservbyname("telnet","tcp" );
  34. memset(&addr_distant,0,sizeof(struct sockaddr_in));
  35. addr_distant.sin_family=PF_INET;
  36. addr_distant.sin_port=htons(service_distant->s_port);
  37. if((inet_aton(argv[1],&addr_distant.sin_addr.s_addr))==0)
  38. printf("\nimpossible de remplir le  champ s_addr" );
  39. /*Creation du point de communicatio*/
  40. if((socket1=socket(AF_INET,SOCK_STREAM,0))<0)
  41. printf("\nCreation de socket echouee" );
  42. /*Connection au point distant*/
  43. connection=connect(socket1,(struct sockaddr*)&addr_distant,sizeof(addr_distant));
  44. /*Procedure de mis en place du mode non bloquant sur stdin*/
  45. tcgetattr(STDIN_FILENO,&term_initial);
  46. tcgetattr(STDIN_FILENO,&term_com);
  47. term_com.c_lflag &=~(ICANON,ECHO);/*,ECHONL,ICANON,IEXTEN);*/
  48. term_com.c_cc[VTIME]=0;
  49. term_com.c_cc[VMIN]=0;
  50. if(tcsetattr(STDIN_FILENO,TCSANOW,term_com)!=0)
  51. printf("\ntransformation du terminal echoue" );
  52. =
  53. /*Modification des delaie pour passer en mode non bloquant*/
  54. delai.tv_sec=0;
  55. delai.tv_usec=0;
  56. while(1)
  57. {/*Debut du while 1*/
  58. /*Initialisation de l'ensemble des descripteurs a multiplexer*/
  59. FD_ZERO (&set);
  60. FD_SET (socket1,&set);
  61. FD_SET (STDIN_FILENO,&set);
  62. /*Selection de l'ensemble des descripteurs a multiplexer en reception*/
  63. if(select(socket1+1,&set,NULL,NULL,&delai)<0)
  64. break;
  65. /*printf("\nOn teste STDIN_FILENO" );*/
  66.       if(FD_ISSET(STDIN_FILENO,&set))
  67.      
  68. {/*Debut du if*/
  69. /*Initialisation d un bloc memoire pour un caractere*/
  70. if((buffer_RX=(char*) calloc (LG_BUFFER,sizeof (char)))==NULL)
  71. printf("\nImpossible d'allouer la memoire buffer_RX STDIN_FILENO" );
  72. nb_lu=0;
  73. if((nb_lu=read(STDIN_FILENO,buffer_RX,LG_BUFFER))<0)
  74. printf("\nerreur sur lecture d'entree ou rien a ecrire retour de nb_lu %d",nb_lu);
  75. if(nb_lu>0)
  76. nb_ec=write(socket1,buffer_TX,nb_lu);
  77. free(buffer_RX);
  78. }/*Fin du if*/
  79. /*printf("\nOn teste socket1" );*/
  80. if(FD_ISSET(socket1,&set))
  81. {/*Debut du if*/
  82. if((buffer_RX=(unsigned char*) calloc (LG_BUFFER,sizeof (unsigned char)))==NULL)
  83. printf("\nImpossible d'allouer la memoire buffer_RX pour socket1" );
  84.  nb_lu=0;
  85.  i=0;
  86. /*Ici on lit temp qu'il y a des donnees a lire on lit sinon on devvrai sortir*/
  87.  while((nb_lu=read(socket1,buffer_RX,LG_BUFFER))>0)
  88.  {/*Debut du while*/
  89.   if(buffer_RX[0]==255)
  90.   {/*Un caractere IAC est arrive*/
  91.   i=1;
  92.   if((mess_nego=(unsigned char*) calloc (i,sizeof (unsigned char)))==NULL)
  93.   printf("\nErreur sur attribution memoire mess_nego" );
  94.   flag_nego_option=1;
  95.   *mess_nego=*buffer_RX;
  96.    while(flag_nego_option==1)
  97.    {/*debut du while*/
  98.    printf("\non est avant realloc valeur de i %d et mess_nego = %d",i,*mess_nego);
  99.    if((mess_nego=realloc(mess_nego,(i+1)*sizeof(unsigned char)))==NULL)
  100.    printf("\nErreur sur attribution memoire" );
  101.    printf("\non passe la realloc de mess_nego[0] qui est a %d *mess_nego[i] est a %d et i est a %d",*(mess_nego),*(mess_nego+i),i);
  102.    nb_lu=read(socket1,mess_nego+i,LG_BUFFER);
  103.     if(*(mess_nego+i)>250 && *(mess_nego+i)<255)
  104.     { /*Phase de test 250>=IAC<255*/
  105.     ++i;
  106.     printf("\nvaleur de i %d",i);
  107.     if((mess_nego=realloc(mess_nego,(i+1)*sizeof(unsigned char)))==NULL)
  108.     printf("\nErreur sur attribution memoire" );
  109.     nb_lu=read(socket1,mess_nego+i,LG_BUFFER);
  110.     printf("\nnouveau mess_nego = ",*(mess_nego+i));
  111.     for(j=0;j<=i;j++)
  112.     printf("\nfor %d j= %d",*(mess_nego+j),j);
  113.     /*OPTION_NEGOCIEE(mess_nego);*/
  114.     }
  115.    flag_nego_option=0;
  116.    free(mess_nego);
  117.    i=++i;
  118.    } /*fin de while(flag_nego_option)*/
  119.    } /*fin de if(buffer_RX[0]==255)*/
  120.    else
  121.    {/*Debut du else*/
  122.    write(STDOUT_FILENO,buffer_RX,nb_lu);
  123.    } /*Fin du else*/
  124.  nb_lu=0;
  125.  }/*fin du while*/
  126.  free(buffer_RX);
  127. }/*Fin du if*/
  128. }/*Fin du while 1*/
  129. close(socket1);
  130. if((tcsetattr(STDIN_FILENO,TCSANOW,term_initial))!=0)
  131. printf("\nremeise en etat du stdin echoue\n" );
  132. }/*fin du main*/

Reply

Marsh Posté le 10-10-2006 à 12:22:32   

Reply

Marsh Posté le 15-10-2006 à 00:54:39    

Rendre la socket non bloquante sert lorsque tu désire faire dautres traitements quand les données ne sont pas encore disponibles.
 
Sinon la socket se comporte comme un flux normal, et si tu le transforme en FILE* tu peux même tester si la fin de fichier est atteinte.
 
Si la connexion est coupé (de force et non avec une fermeture logicielle de socket close() ou fclose()) la lecture sur la socket peut échouer mais au bout de quelques secondes d attente.
 
Le problème vient d ailleurs. Pense à tester errno (include errno.h).


Message édité par nargy le 15-10-2006 à 00:55:47
Reply

Marsh Posté le 16-10-2006 à 09:34:20    

En effet c'est ce que j'ai fait.
Merci

Reply

Sujets relatifs:

Leave a Replay

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