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

  FORUM HardWare.fr
  Programmation
  C++

  problème taille de buffer /socket

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

problème taille de buffer /socket

n°318644
Nico5779
Posté le 26-02-2003 à 19:33:34  profilanswer
 

bonjour,
Je voudrait faire un programme qui fait un genre de tunnel, pour rediriger les connexions entrantes sur le port XX vers le port port YY de la machine A.B.C.D  
 
g taper le code suivant

Code :
  1. #ifdef unix
  2. #define closesocket close
  3. #include <sys/types.h>
  4. #include <sys/socket.h>
  5. #include <netinet/in.h>
  6. #include <arpa/inet.h>
  7. #include <netdb.h>
  8. #else
  9. #define WIN32
  10. #include <windows.h>
  11. #include <winsock.h>
  12. #endif
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include <iostream.h>
  16. #define WEBPORT 2000
  17. #define LOCALPORT 80
  18. #define BUFFER 100000
  19. #define QLEN 6
  20. int visits = 0;
  21. extern int errno;
  22. char localhost[] = "192.168.0.81";
  23. int sizeString(char buf[BUFFER]);
  24. int main ()
  25. {
  26. struct hostent *ptrh_cli;
  27. struct protoent *ptr_serveur,*ptrp_client;
  28. struct sockaddr_in serveur,sad_cli,sad_serv;
  29. int port_cli,sd_cli,n_cli,alen,port,sd,sd2,n,i = 0;;
  30. char *host_cli;
  31. char buffer[BUFFER],buf_cli[BUFFER];
  32. while (i < BUFFER)
  33. {
  34.  buffer[i] = '*';
  35.  buffer2[i] = '*';
  36.  buf_cli[i] = '*';
  37.  i++;
  38. }
  39. #ifdef WIN32
  40. WSADATA wsaData;
  41. WSAStartup(0x0101 , &wsaData);
  42. #endif
  43. memset((char *)&sad_serv,0,sizeof(sad_serv));
  44. sad_serv.sin_family = AF_INET;
  45. sad_serv.sin_addr.s_addr = INADDR_ANY;
  46. port = WEBPORT;
  47. sad_serv.sin_port = htons((u_short) port);
  48. if (((int)(ptr_serveur = getprotobyname("tcp" ))) ==0)
  49. {
  50.  cerr<<"failed to get prtocol by name"<<endl;
  51.  exit(1);
  52. }
  53. sd = socket(PF_INET, SOCK_STREAM , ptr_serveur->p_proto);
  54. if (sd < 0)
  55. {
  56.  cerr<<"erreur while initializing socket"<<endl;
  57.  exit(1);
  58. }
  59. if (bind(sd,(struct sockaddr *)&sad_serv, sizeof(sad_serv))<0)
  60. {
  61.  cerr<<"error while binding socket"<<endl;
  62.  exit(1);
  63. }
  64. if (listen(sd ,QLEN) >= 0)
  65. {
  66.  cout<<"Listening port "<<port<<"..."<<endl;
  67. }
  68. else
  69. {
  70.  cerr<<"failed to listen port "<<port<<" ..."<<endl;
  71.  exit(1);
  72. }
  73. memset((char *) &sad_cli,0,sizeof(sad_cli));
  74. sad_cli.sin_family = AF_INET;
  75. port_cli = LOCALPORT;
  76. sad_cli.sin_port = htons ((u_short)port_cli);
  77. host_cli = localhost;
  78. ptrh_cli = gethostbyname(host_cli);
  79. if (((char *)ptrh_cli) == NULL)
  80. {
  81.  cerr<<"host unknown"<<host_cli<<endl;
  82.  exit(1);
  83. }else
  84. {
  85.  cout<<"attempting to reach "<<(char *)ptrh_cli->h_name<<" ..."<<endl;
  86. }
  87. memcpy(&sad_cli.sin_addr , ptrh_cli->h_addr,ptrh_cli->h_length);
  88. if (((int)(ptrp_client = getprotobyname("tcp" ))) == 0)
  89. {
  90.  cerr<<"failed to get prtocol by name"<<endl;
  91.  exit(1);
  92. }
  93. //listen(sd,QLEN);
  94. while(true)
  95. {
  96.  alen = sizeof(serveur);
  97.  if ((sd2=accept(sd,(struct sockaddr *)&serveur ,&alen))<0)
  98.  {
  99.   cerr<<"unable to accept remote user\n"<<endl;
  100.   exit(1);
  101.  }else
  102.  {
  103.   visits++;
  104.   cout<<endl<<"connection id: "<<visits<<endl;
  105.  }
  106.  sd_cli = socket(PF_INET, SOCK_STREAM, ptrp_client->p_proto);
  107.  if(sd_cli < 0)
  108.  {
  109.   cerr<<"erreur while initializing socket"<<endl;
  110.   exit(1);
  111.  }
  112.  if (connect(sd_cli,(struct sockaddr *)& sad_cli,sizeof(sad_cli)) >= 0)
  113.  {
  114.   cout<<"*** connected to "<<localhost<<" ***"<<endl;
  115.  }else
  116.  {
  117.   cerr<<"attempt to connect "<<localhost<<" failed ... aborting"<<endl;
  118.   exit(1);
  119.  }
  120.  n = recv(sd2,buffer,sizeof(buffer),0);
  121.  send (sd_cli,buffer,strlen(buffer),0);
  122.  n_cli = recv(sd_cli,buf_cli,sizeof(buf_cli),0);
  123.  send (sd2,buf_cli,sizeString(buf_cli)-1,0);
  124.  closesocket(sd_cli);
  125.  closesocket(sd2);
  126. }
  127. return 0;
  128. }
  129. int sizeString(char buf[BUFFER])
  130. {
  131. int i = 0;
  132. bool b = true;
  133. while (i < BUFFER && b == true)
  134. {
  135.  int j = i,c=0;
  136.  while (j<i+15)
  137.  {
  138.   if(buf[j] == '*')
  139.    c++;
  140.   j++;
  141.  }
  142.  if (c >= 14)
  143.   b = false;
  144.  i++;
  145. }
  146. return i;
  147. }


 
a priori ca fonctionne mais lorsque que j'essaye de transferer un buffer suprérieur a 10220 bytes ca foire  :(  
Je vois pas trop comment m'y prendre ...si vous pouvez me guider sur le principe pour gerer les transferts en paquets...
Merci d'avance  :jap:

mood
Publicité
Posté le 26-02-2003 à 19:33:34  profilanswer
 

n°318760
kenshiro18​2
Posté le 26-02-2003 à 21:44:02  profilanswer
 

Euh il aime peut-etre pas les variables globales trop grosses ?
Decris exactement ce qui se passe... Utilise un debugger...

n°318782
Nico5779
Posté le 26-02-2003 à 22:05:44  profilanswer
 

Ben concrètement je teste le prog avec un serveur web sur la machine A.B.C.D , et si la page (ou image) est supérieur a 10ko elle s'affiche pas ou mal dans le navigateur, alors que je crée un buffer de 100ko pour stocker les données transferées.
Lorsque j'affiche la taille du buffer en cours elle vaut tj 10220 maximum (ou moins lorsque chaque objet de la page est < 10ko)

n°319331
Nico5779
Posté le 27-02-2003 à 15:30:38  profilanswer
 

un bon vieux up  :bounce:

n°319337
western
AJMM
Posté le 27-02-2003 à 15:38:23  profilanswer
 

un buffer de 100000 octets ... :pt1cable:  
vous etes les meilleurs!
Petite question: pourquoi un buffer aussi gros? 2048 est une taille raisonnable ...

n°319451
Nico5779
Posté le 27-02-2003 à 15:57:37  profilanswer
 

ben c présicément mon prob...
d'abord je n arrive pas remplir les 100000 bytes du buffer,
Et ensuite c justement ske je voulais savoir comment gerer des transfert de gros fichiers en ptit paquet avec un ptit buffer.

n°319496
western
AJMM
Posté le 27-02-2003 à 16:25:13  profilanswer
 

les paquets TCP ou UDP a une taille maximal qui n'est pas très grande ... tout est découpé en morceaux et reassemblé par le destinataire donc un gros buffer n'a pas d'intérêt ...
Comment lire un gros fichier? Comme les petits:  
 

Code :
  1. FILE * peripherique = fopen(fichier_in, "r" );
  2.   if(peripherique == NULL)
  3.     {
  4. //on arrete tout!
  5.     }
  6.   FILE * fichier_iso = fopen(fichier_out, "w" );
  7.   if(fichier_iso == NULL)
  8.     {
  9.          fclose(peripherique);
  10. //on arrete tout!
  11.     }
  12.   int taille_lu = 1;
  13.   while(taille_lu >= 0)
  14.     {
  15.       taille_lu = read(fileno(peripherique), buffer, taille);
  16.       progression = progression + ((double)taille_lu * 100)/(double)taille_cd;
  17.       printf("progression = '%f'\n", progression);
  18.       if(taille_lu == 0)
  19.         {
  20.           //fini
  21.           resultat = 0;
  22.           break;
  23.         }
  24.       if(taille_lu < 0)
  25.         {
  26.           //un error a eu lieu!
  27.           fprintf(stderr, "L'erreur '%s' a eu lieu pendant l'extraction du iso\n", strerror(errno));
  28.           unlink(nom_iso.val());
  29.           progression=0.0;
  30.           break;
  31.         }
  32.       write(fileno(fichier_iso), buffer, taille_lu);
  33.     }
  34.   fclose(fichier_iso);
  35.   fclose(peripherique);

 
Cet extrait de code permet de copier un fichier de taille quelconque ... il suffit que tu remplace fichier_iso par ta socket!
 
EDIT: pas terrible, la rendue ...


Message édité par western le 27-02-2003 à 16:26:10
n°319515
Nico5779
Posté le 27-02-2003 à 16:50:42  profilanswer
 

merci  :jap:  
J'en ai pour l'aprem avec ca , mais tant mieux y fait bo , (et moi j aime la pluie  :D )
Je voudrait juste etre sur d'avoir compris la méthode,
Donc peripherique c le fichier qui contient ce que je veux transferer?
Et lorsque tu fait write fichier_iso je doit faire un send ?
ca bien ca?
Et est que la méthode peut s appliquer pour recevoir un fichier (en inversant les fonctions)?
Encore merci pour ton aide  :)

n°319535
western
AJMM
Posté le 27-02-2003 à 17:06:26  profilanswer
 

bingo! cela doit être ça! (cela fait au moins deux ans que j'ai pas touché aux sockets en C)

n°319550
Nico5779
Posté le 27-02-2003 à 17:17:28  profilanswer
 

oki nikel  ,encore merci  :jap:  
une dernière question ( je pousse la  :D )
Vous me conseillez quoi comme sentinelle mieux 15 '*'.
Le char 4 (EOT) sert a ca ?

mood
Publicité
Posté le 27-02-2003 à 17:17:28  profilanswer
 

n°319689
Nico5779
Posté le 27-02-2003 à 19:40:11  profilanswer
 

heu voila je vien de taper ca

Code :
  1. #ifndef unix
  2. #define WIN32
  3. #include <windows.h>
  4. #include <winsock.h>
  5. #else
  6. #define closesocket close
  7. #include <sys/types.h>
  8. #include <sys/socket.h>
  9. #include <netinet/in.h>
  10. #include <netdb.h>
  11. #endif
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <iostream.h>
  15. #include <fstream.h>
  16. #define PROTOPORT 2000
  17. #define QLEN 6
  18. #define SIZEOFBUFFER 5000
  19. int visits = 0;
  20. char * filename ="d:/mod/test/Debug/q3iscr.jpg";
  21. void main ()
  22. {
  23. int i = 0;
  24. int size=0;int j = 0;
  25. struct hostent *ptrh;
  26. struct protoent *ptrp;
  27. struct sockaddr_in cad;
  28. struct sockaddr_in sad;
  29. int sd,sd2;
  30. int port;
  31. int alen;
  32. int n;
  33. char buffer[SIZEOFBUFFER];
  34. #ifdef WIN32
  35. WSADATA wsaData;
  36. WSAStartup(0x0101 , &wsaData);
  37. #endif
  38. memset((char *)&sad,0,sizeof(sad));
  39. sad.sin_family = AF_INET;
  40. sad.sin_addr.s_addr = INADDR_ANY;
  41. port = PROTOPORT;
  42. if (port > 0)
  43. sad.sin_port = htons((u_short) port);
  44. else
  45. {
  46.  fprintf(stderr,"numero de port invalide" );
  47.  exit(1);
  48. }
  49. if (((int)(ptrp = getprotobyname("tcp" ))) ==0)
  50. {
  51.  fprintf (stderr,"conversion de \"tcp\" impossible" );
  52.  exit(1);
  53. }
  54. sd = socket(PF_INET, SOCK_STREAM , ptrp->p_proto);
  55. if (sd < 0)
  56. {
  57.  fprintf(stderr,"erreur (socket)\n" );
  58.  exit(1);
  59. }
  60. if (bind(sd,(struct sockaddr *)&sad, sizeof(sad))<0)
  61. {
  62.  fprintf(stderr,"erreur (bind)\n" );
  63.  exit(1);
  64. }
  65. if (listen(sd ,QLEN < 0))
  66. {
  67.  fprintf(stderr,"erreur (listen)\n" );
  68.  exit(1);
  69. }
  70. cout<<"Listening port "<<port<<"..."<<endl;
  71. while (1)
  72. {
  73.  alen = sizeof(cad);
  74.  if ((sd2=accept(sd,(struct sockaddr *)&cad ,&alen))<0)
  75.  {
  76.   fprintf(stderr,"accept failed\n" );
  77.   exit(1);
  78.  }else
  79.  {
  80.   cout<<endl<<"conection id: "<<visits<<endl;
  81.  }
  82.  visits++;
  83.  ifstream file (filename, ios::in|ios::binary|ios::ate);
  84.  size = file.tellg();
  85.  file.seekg (0, ios::beg);
  86.  i = 0;
  87.  while(j < size/SIZEOFBUFFER)
  88.  {
  89.   j++;
  90.  }
  91.  int lastbuf = size - (j*SIZEOFBUFFER);
  92.  while(i <= size/SIZEOFBUFFER)
  93.  {
  94.   file.read(buffer, SIZEOFBUFFER);
  95.   cout<<"lecture buffer:"<<i<<endl;
  96.   if(i == j )
  97.   {
  98.    send (sd2,buffer,lastbuf,0);
  99.    cout<<lastbuf<<" bytes sended"<<endl;
  100.   }else
  101.   {
  102.    send (sd2,buffer,SIZEOFBUFFER,0);
  103.    cout<<SIZEOFBUFFER<<" bytes sended"<<endl;
  104.   }
  105.   i++;
  106.  }
  107.  file.close();
  108.  cout<<endl<<"******************************"<<endl;
  109.  closesocket(sd2);
  110. }
  111. }


La y as plus qu'un socket , c juste pour tester.
La ca marche , en fait je peut transferer par exemple une image (qui pour l'instant est sur le disque local),
Mais le prob dans ie elle s'affiche très bien mais sous d'autre nav comme mozilla ou konqueror ca foire.
Qd ca sera le contenu renvoyer par le apache de l'autre machine (qd j aurais mis l'autre socket) ca marchera la?

n°319921
Nico5779
Posté le 27-02-2003 à 23:57:13  profilanswer
 

bon voila g capter comment ca marchait ,c t pas nécessaire d'utiliser un fichier en fait , mais c qd meme ca qui ma mis sur la voie   ;)  
Et les deux problèmes ci dessus se sont bien résolu d eux meme comme j esperait  :)  
c t tout con en fait...

Code :
  1. #ifndef unix
  2. #define WIN32
  3. #include <windows.h>
  4. #include <winsock.h>
  5. #else
  6. #define closesocket close
  7. #include <sys/types.h>
  8. #include <sys/socket.h>
  9. #include <netinet/in.h>
  10. #include <netdb.h>
  11. #endif
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <iostream.h>
  15. #include <fstream.h>
  16. #define SIZEOFBUFFER 2000
  17. #define WEBPORT 2000
  18. #define LOCALPORT 80
  19. #define QLEN 6
  20. extern int errno;
  21. char localhost[] = "192.168.0.81";
  22. char * filename ="d:/mod/test/Debug/tmp.dat";
  23. int visits = 0;
  24. void main ()
  25. {
  26. ofstream file (filename, ios::in|ios::binary|ios::ate);
  27. int size=0;int j = 0;
  28. struct hostent *ptrh_cli;
  29. struct protoent *ptr_serveur,*ptrp_client;
  30. struct sockaddr_in serveur,sad_cli,sad_serv;
  31. int port_cli,sd_cli,n_cli,alen,port,sd,sd2,n,i = 0;
  32. char buffer[SIZEOFBUFFER],buf_cli[SIZEOFBUFFER];
  33. char *host_cli;
  34. while (i < SIZEOFBUFFER)
  35. {
  36.  buffer[i] = '*';
  37.  buf_cli[i] = '*';
  38.  i++;
  39. }
  40. #ifdef WIN32
  41. WSADATA wsaData;
  42. WSAStartup(0x0101 , &wsaData);
  43. #endif
  44. memset((char *)&sad_serv,0,sizeof(sad_serv));
  45. sad_serv.sin_family = AF_INET;
  46. sad_serv.sin_addr.s_addr = INADDR_ANY;
  47. port = WEBPORT;
  48. sad_serv.sin_port = htons((u_short) port);
  49. if (((int)(ptr_serveur = getprotobyname("tcp" ))) ==0)
  50. {
  51.  cerr<<"failed to get prtocol by name"<<endl;
  52.  exit(1);
  53. }
  54. sd = socket(PF_INET, SOCK_STREAM , ptr_serveur->p_proto);
  55. if (sd < 0)
  56. {
  57.  cerr<<"erreur while initializing socket"<<endl;
  58.  exit(1);
  59. }
  60. if (bind(sd,(struct sockaddr *)&sad_serv, sizeof(sad_serv))<0)
  61. {
  62.  cerr<<"error while binding socket"<<endl;
  63.  exit(1);
  64. }
  65. if (listen(sd ,QLEN) >= 0)
  66. {
  67.  cout<<"Listening port "<<port<<"..."<<endl;
  68. }
  69. else
  70. {
  71.  cerr<<"failed to listen port "<<port<<" ..."<<endl;
  72.  exit(1);
  73. }
  74. memset((char *) &sad_cli,0,sizeof(sad_cli));
  75. sad_cli.sin_family = AF_INET;
  76. port_cli = LOCALPORT;
  77. sad_cli.sin_port = htons ((u_short)port_cli);
  78. host_cli = localhost;
  79. ptrh_cli = gethostbyname(host_cli);
  80. if (((char *)ptrh_cli) == NULL)
  81. {
  82.  cerr<<"host unknown"<<host_cli<<endl;
  83.  exit(1);
  84. }else
  85. {
  86.  cout<<"attempting to reach "<<(char *)ptrh_cli->h_name<<" ..."<<endl;
  87. }
  88. memcpy(&sad_cli.sin_addr , ptrh_cli->h_addr,ptrh_cli->h_length);
  89. if (((int)(ptrp_client = getprotobyname("tcp" ))) == 0)
  90. {
  91.  cerr<<"failed to get prtocol by name"<<endl;
  92.  exit(1);
  93. }
  94. //listen(sd,QLEN);
  95. while (1)
  96. {
  97.  alen = sizeof(serveur);
  98.  if ((sd2=accept(sd,(struct sockaddr *)&serveur ,&alen))<0)
  99.  {
  100.   fprintf(stderr,"accept failed\n" );
  101.   exit(1);
  102.  }else
  103.  {
  104.   cout<<endl<<"conection id: "<<visits<<endl;
  105.  }
  106.  visits++;
  107.  i = 0;
  108.  sd_cli = socket(PF_INET, SOCK_STREAM, ptrp_client->p_proto);
  109.  if(sd_cli < 0)
  110.  {
  111.   cerr<<"erreur while initializing socket"<<endl;
  112.   exit(1);
  113.  }
  114.  if (connect(sd_cli,(struct sockaddr *)& sad_cli,sizeof(sad_cli)) >= 0)
  115.  {
  116.   cout<<"*** connected to "<<localhost<<" ***"<<endl;
  117.  }else
  118.  {
  119.   cerr<<"attempt to connect "<<localhost<<" failed ... aborting"<<endl;
  120.   exit(1);
  121.  }
  122.  n = recv(sd2,buffer,sizeof(buffer),0);
  123.  send (sd_cli,buffer,n,0);
  124.     n_cli=5000;
  125.  while (n_cli != 0 && n_cli != -1)//c t juste cette boucle ki fallait faire
  126.  {
  127.   n_cli = recv(sd_cli,buf_cli,sizeof(buf_cli),0);
  128.   //file.write(buf_cli,n_cli);
  129.   if (n_cli != 0)
  130.   send (sd2,buf_cli,n_cli,0);
  131.   cout<<n_cli<<"bytes transfered"<<endl;
  132.  }
  133.  closesocket(sd_cli);
  134.         //file.close();
  135.  cout<<endl<<"******************************"<<endl;
  136. }
  137.         closesocket(sd2);
  138. }


Mais y reste encore un prob c que c très (trop) lent...
Entre chaque requete transmise puis retransmise y as des long moment ou y fout rien ...Et je vois pas ou est le prob  :(  
Si par exemple j'arriverait a faire le meme algo mais en me connectant qu'une seule fois a l autre machine (192.168.0.81)  
j'y gagnerait bcp?
Si qqn peut encore m'aider ca serait super   :jap:


Message édité par Nico5779 le 27-02-2003 à 23:59:19
n°320010
western
AJMM
Posté le 28-02-2003 à 09:31:54  profilanswer
 

Amigo, soit tu fais du C (memcpy) soit du C++(cout) ... Il ne faut pas melanger les choses car cela est une très mauvaise pratique (pas de troll, svp)
Pour tes problèmes, plutard peut-être car là
1) je ne suis pas reveillé (une mauvaise nuit);
2) j'ai très mal à la gorge, à la tête (une mauvaise nuit) et pour courronner le tout un nez qui n'arrete pas de couler ...

n°320559
Nico5779
Posté le 28-02-2003 à 21:03:31  profilanswer
 

je suis d'accord avec toi en ce qui concerne les normes , mais c le genre de detail que je regle qd ca marche.
Or la ...  :sweat:  
Sinon jte souhaite un bon retablissement  :)  
Les autres, si vous avez des remarques qui pourrait m'aider ne vous genez pas  :)

n°321170
Nico5779
Posté le 02-03-2003 à 18:36:18  profilanswer
 

bon je crois que j'ai trouver ,le prob venait quand y recevait le dernier paquet de taille zero,
Mais g encore des probs  :(  
Je voulait utiliser le flag MSG_EOR
Mais visual me sort qu'il le connait pas.
 
edit: le prob avec gcc est resolu mais pas l'autre...
redit: nan en fait c MSG_WAITALL le bon flag mais c pareil visual me sort tj qu'il le connait pas... :/


Message édité par Nico5779 le 02-03-2003 à 18:51:10

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

  problème taille de buffer /socket

 

Sujets relatifs
[SQL ACCESS] problème de syntaxe avec les JOINProblème SQL sous Oracle
XSL + Javascript -> probleme :(Problème en VBA pour remplir une case ! ! ! !
[CSS/HTML] Ya moyen de changer la taille de la scrollbar ???[NASM] problème pour utiliser le port 378h (parallele) sous XP ...
[DBGrid] Taille du déplacement horizontal ?Apache et Tomcat : problème de session ?
[C++] tronquer un fichier à une certaine tailleProblème de Parse Error que j'arrive pas a résoudre...
Plus de sujets relatifs à : problème taille de buffer /socket


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