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

  FORUM HardWare.fr
  Programmation
  C

  Reseau Socket - Problème de bind() dans un client/serveur local

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Reseau Socket - Problème de bind() dans un client/serveur local

n°883785
Piper1664
Posté le 27-10-2004 à 11:56:34  profilanswer
 

Salut a tous,
 
Je suis sur un projet de client/serveur ftp en C sous unix. Je le teste en local pour le moment. Je suis débutant en réseau et il s'agit d'un projet basique.
J'essaye de faire passer un fichier du serveur vers le client, à partir d'un fichier source sur le serveur.
 
Lorsque je lance le client, tout se déroule normalement (en tout cas apparament)
 
Mais lorsque Je veux renouveller l'opération (après avoir closé le socket, le fichier, effacé le fichier copié etc...) ca ne fonctionne plus.
Le bind ne marche plus !
 
Si quelqu'un connait différentes raisons qui peuvent amener a un plantage du bind, merci de me tenir au courant ca me serait tres utile !
 

mood
Publicité
Posté le 27-10-2004 à 11:56:34  profilanswer
 

n°883790
Taz
bisounours-codeur
Posté le 27-10-2004 à 12:07:04  profilanswer
 

Piper1664 a écrit :

merci de me tenir au courant ca me serait tres utile !

tu veux pas plutôt filer des messages d'erreurs ? et pourquoi tu fais 36 bind dans ton programme ? t'as fait des vérifications d'erreur, utilise perror, etc :o

n°883793
Piper1664
Posté le 27-10-2004 à 12:11:12  profilanswer
 

Non en réalité je ne fais qu'un bind. Ce que je veux dire, c'est qu'après avoir arreté le serveur puis redémarré, la le bind ca marche plus.
Je n'ai pas de message d'erreur a part mon printf perso (apres renvoit -1).
je veux bien filer mes messages d'erreur mais je sais pas comment on fait pour utiliser perror ? sinon j'avais vu que le bind utilisait bgerror. c'est pareil ? comment on l'utilise stp ?
 
merci bcp !!

n°883816
Taz
bisounours-codeur
Posté le 27-10-2004 à 12:31:04  profilanswer
 

setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))
 
man perror :o

n°883829
Piper1664
Posté le 27-10-2004 à 12:54:01  profilanswer
 

ok merci.
 
Alors perror me renvoit "address already in use"
[j'ai mis perror(bind) mais jsuis pas sur que ce soit la bonne syntaxe. je comprend pas trop quel est l'argument a mettre (char * include the name of the function...)]
quand je quitte le serveur, je fais un close(sock).
Il faut peut etre libérer l'adresse du bind mais jsais pas trop de laquelle il s'agit et de comment on fait.
 
qu'en penses tu ?  
 
merci d'avance
 
P.S : a koi sert setsockopt (j'ai maté avec man mais jpige pas trop l'intéret) :-S

n°883831
Taz
bisounours-codeur
Posté le 27-10-2004 à 12:57:15  profilanswer
 

sans déconner ...
 
man setsockopt + SO_REUSEADDR

n°883832
Piper1664
Posté le 27-10-2004 à 12:58:58  profilanswer
 

ah j'imagine que le SO_REUSEADDR permet de réutiliser l'adresse... hum hum

n°883833
Piper1664
Posté le 27-10-2004 à 13:00:49  profilanswer
 

lol dsl si ca parait pas évident pour moi mais mon man il me parle pas de so_reuseaddr... enfin maintenant que j'ai tilté...

n°883836
Piper1664
Posté le 27-10-2004 à 13:18:25  profilanswer
 

bon j'ai intégré set sockopt. ca marche toujours qu'une seule fois apres delog et relog. je sais pas ce que j'ai mal fait.
 
si tu as le temps de mater un peu le code (regarde au niveau du bind) merci beaucoup
___________________________________________________________
 
 
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>   // Gestion Fichier  
#include <malloc.h>   // Fonctions mémoire
#include <stdlib.h>   // Fonctions mémoire
 
// ---------------- DECLARATION FONCTIONS
void Serveur(void);   // Le Serveur
void Erreur(char *);  // Erreur Fatale au Serveur
 
// ---------------- CONSTANTES + VARIABLES GLOBALES  
#define FICHIER  "source.txt" // Fichier Source
#define FICH_MAX_SIZE 10000 // Taille Maximum de Fichier  
#define PORT_SERVEUR 4000  // Numéro Port du Socket Serveur (1 à 65535)
 
int sock;     // La Socket
struct sockaddr_in sinfo;    // Infos sur la Socket
int sinfosize;     // Taille structure sinfo
FILE *fich;      // Pointeur fichier Source
void *on;
 
// *********
// main
// *********
int main()
{
 
 while(1) Serveur(); // Lancement du Serveur Jamais d'arrêt du Serveur
 return 0;   //fin du programme (jamais atteind !)
}
 
 
 
// *********
// Serveur  
// *********
void Serveur(void)
{
 int Etat;    // Retour des commandes Socket
 int ServeurON;   // false => Fin Serveur , true => Serveur en route
 char *buffer;   // buffer memoire, va contenir le fichier
 int TailleFichier;  // Taille Fichier
 
 
// __________________________ CREATION SOCKET __________________________________________
 
 
 sock=socket(AF_INET,SOCK_STREAM,0);  // Tentative Creation Socket
 if (sock==-1)
 {
 fprintf(stderr,"-------------ERREUR------------ Creation Socket Impossible !\n" );  
 exit(0);
 }
 
 fprintf(stderr,"Socket crée ! --------- OK\n" );
 
 sinfo.sin_addr.s_addr = htonl(INADDR_ANY);  // @IP Socket = @IP Ordinateur
 sinfo.sin_family = AF_INET;    // Protocole internet  
 sinfo.sin_port = htons(PORT_SERVEUR); // Port du Socket Serveur
 
 setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)); // pour réutiliser l'adresse pour un bind ulterieur
 
 
// ________________________________ BIND _______________________________________________
 
 
 Etat=bind(sock,(struct sockaddr *)&sinfo,sizeof(sinfo)); // Attache Socket  
 if (Etat==-1)
 {
 fprintf(stderr,"-----------ERREUR---------- Socket: Bind Impossible !\n" );  
 perror(bind);
 close(sock);
 exit(0);
 }
 
 fprintf(stderr,"Bind réussi ! -------- OK\n" );
 
// _____________________________ LISTEN ________________________________________________
 
 
 Etat=listen(sock,0);     // Mise en écoute Socket
 if (Etat<0)
 {
 fprintf(stderr,"----------ERREUR----------- Socket: Ecoute Impossible !\n" );  
 close(sock);
 exit(0);
 }
 
 fprintf(stderr,"Mise en écoute ------- OK\n" );
 
 ServeurON=1;       // Le Serveur à démarré
 
 fprintf(stderr,"ServeurON mis à %d\n",ServeurON);
 
 
// _______________________ RESERVATION BUFFER MEMOIRE __________________________________
 
 if ((buffer=(char *)malloc(FICH_MAX_SIZE))==NULL)
 {
 fprintf(stderr,"-----------ERREUR------------ Reservation Memoire Impossible !\n" );  
 close(sock);
 exit(0);
 }
 
 fprintf(stderr,"Réservation mémoire -------- OK\n" );
 
 
// ______________________________________  BOUCLE SERVEUR _________________________________________________
 
 
 while(ServeurON==1)     // Boucle permanente tant que ServeurON=true
 {
  sinfosize = sizeof(sinfo);   // Taille Structure sinfo
   
// _____________________________ ACCEPT
 
  if((sock=accept(sock,(struct sockaddr *)&sinfo,&sinfosize))!= -1)
  {  
   // OK LE SERVEUR A ACCEPTE LA CONNECTION CLIENT
   fprintf(stderr,"CONNEXION ETABLIE ----------- OK\n" );
 
// ____________________________ FICHIER
 
   if ((fich=fopen(FICHIER,"rb" ))==NULL)
   {
   fprintf(stderr,"----------ERREUR------- Ouverture Fichier Impossible !\n" );
   close(sock);
   exit(0);
   }
   fprintf(stderr,"Fichier %s ouvert ----------- OK\n",FICHIER);
   
   TailleFichier=fread(buffer,1,FICH_MAX_SIZE,fich); // Lecture dans FICHIER
   fprintf(stderr,"TailleFichier = %d\n",TailleFichier);
   
// ____________________________ SEND
 
   if (send(sock,buffer,TailleFichier,0)<0)
   {
   fprintf(stderr,"----------ERREUR-------- Erreur send transmission du Serveur !\n" );
   close(sock);
   exit(0);
   }
   fprintf(stderr,"SEND ------------ OK\n" );
 
   
// ___________________________ CLOSE
 
   fclose(fich); // Fermeture Fichier
   ServeurON=-1;
   fprintf(stderr,"ServeurON = %d\n",ServeurON);
 
   
  } else { fprintf(stderr,"--------ERREUR------- CONNEXION BAAAD, ACCEPT FOIREUX !!!\n" ); }
 }
 
// ________________________________________ FIN BOUCLE SERVEUR _________________________________________
 
 
 free(buffer);    // Libère mémoire
 sleep(1000);    // 1 secs d'attente => le client se deconnecte avant
 close(sock);   // Fermeture Socket
 fprintf(stderr,"-------- FIN SERVEUR ---------" );
}

n°883838
Taz
bisounours-codeur
Posté le 27-10-2004 à 13:20:27  profilanswer
 

mais pourquoi tu fais 36 bind bordel, 36 sockets ...
 
 
ta boucle principal, ça doit être ton accept !

mood
Publicité
Posté le 27-10-2004 à 13:20:27  profilanswer
 

n°883850
Piper1664
Posté le 27-10-2004 à 13:32:31  profilanswer
 

ah d'accord, je pense que je comprenais mal l'utilisation du socket. je pensais qu'a chaque envoi correspondait un nouveau socket puis une fois fini sa destruction...
donc le socket est toujours ouvert ? ca ne pose pas de pb de sécurité ?
mais mon code pourrait marcher si on fermait bien le socket, l'addresse etc en fin de boucle du serveur, non ?
 
mais si je fais comme tu dis, il faut forcément le listen dans la boucle (avant le accept)!
 
ou alors j'ai vraiment pas saisi le concept...
merci de m'éclairer niveau sens, et désolé de te prendre la tete mais jsuis encore très novice et je lutte pas mal (tout le monde y passe non ?) ;-)

n°883852
Taz
bisounours-codeur
Posté le 27-10-2004 à 13:34:33  profilanswer
 

t'as vraiment rien compris entre socket public et socket privé ...

n°883869
Piper1664
Posté le 27-10-2004 à 13:59:51  profilanswer
 

wouaw, c'est constructif comme réponse :-D
si j'avais tout compris jserais pas la !
toi par contre, t'y es et t'as tout compris, j'imagine donc qu'aider les autres c'est une passion pour toi. Je te remercie d'ailleurs de bien vouloir répondre à mes problèmes (t'es le seul pour le moment, après tout), mais ton arrogance et ta fierté de programmeur expert né tout le monde s'en passerait bien. Contrairement à ton humilité.
 
merci quand meme... :-(

n°883876
Lam's
Profil: bas.
Posté le 27-10-2004 à 14:12:41  profilanswer
 

Taz, si t'excite autant les filles que les nouveaux sur le forum, tu dois être un homme comblé...
 
Sinon Piper, il faut toujours garder ta socket d'écoute ouverte, et oui, ça pose des problèmes de sécurité (à toi de vérifier que ceux qui se connectent à ta socket le font proprement).  
 
Donc, la fonction "accept" te renvoie une socket d'échange. Mets la dans une autre variable que "sock" (qui est ta socket d'écoute), et c'est cette socket d'échange qu'il te faut fermer dans ta boucle.
 

n°883881
Piper1664
Posté le 27-10-2004 à 14:15:11  profilanswer
 

aaah merci beaucoup Lam's, c'est tout de suite plus clair, je vais essayer ca :-)

n°883999
Piper1664
Posté le 27-10-2004 à 15:50:55  profilanswer
 

merci beaucoup Lam's, ca fonctionne nikel !!
je comprends mieux le concept maintenant.
 
Reste a intégrer les différentes commandes sur le meme principe...
:-D


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

  Reseau Socket - Problème de bind() dans un client/serveur local

 

Sujets relatifs
Passage 1.3.1 à 1.4.2 : question socketProblème avec la fonction MoveFile [Résolu]
[C] Probleme de conversion char -> intPOSIX et la portabilité Windows (API réseau)
Problème de transfert de Paradox vers MSSQLclient/serveur par socket
création d'une image dynamique téléchargeable par le clientProbleme avec une requête
Plus de sujets relatifs à : Reseau Socket - Problème de bind() dans un client/serveur local


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