IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

[Reseau] Comment faire attendre la connection d'un socket


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2007
    Messages
    387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2007
    Messages : 387
    Par défaut [Reseau] Comment faire attendre la connection d'un socket
    Bonjour,

    Je suis assez surpris de ce problème, n'utilisant pas encore de Thread, donc je voudrais savoir pourquoi il intervient.
    J'envoie à un socket des données (connection au serveur FTp, User,Password,etc..), mais si je ne met pas quelquechose pour faire une pause (une fenêtre que l'utilisateur doit cliquer, par exemple), la connection au serveur se fait avant que celui-ci n'ai recu toutes les informations.
    Il peut, par exemple, avoir récu la demande de connection, le nom d'User, mais pas le Mot de passe, ni ce qui suit ces instructions.
    Si j'aurais utilisé des threads, j'aurait compris le problème, mais là, il est censé attendre qu'une instruction soit finie pour passer à une autre.
    Surtout que j'utilise la fonction regarder qui regarde si le serveur ne me renvoie pas -1 après l'envoie du send(), donc....

    Donc ma question est : comment obliger le serveur (ou le programme), à attendre que l'envoi des données soit effective avant de continuer ?

    voici le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
     
    ...
    int rep=connect(sock, (sockaddr*)&sin, sizeof(sin));
    ...
    std::ostringstream oss;
    			oss<<"USER anonymous\r\n";//PASS a.a@msn.fr CWD ankamagam RETR Errata.txt";
    			strcpy_s(TEMP,512,oss.str().c_str());
    			int rep=send(sock, TEMP, (int)strlen(TEMP), 0);
    			regarder(rep);
    			//Sleep(20);
    			//MessageBoxA(hDlg,"PASSEFtp 8","oidcvn",MB_OK);
    			oss.clear();
    			std::ostringstream oss1;
    			oss1<<"PASS a.a@msn.fr\r\n";
    			strcpy_s(TEMP,512,oss1.str().c_str());
    			rep=send(sock, TEMP, (int)strlen(TEMP), 0);
    			regarder(rep);
    			//Sleep(20);
    			//MessageBoxA(hDlg,"PASSEFtp 8","oidcvn",MB_OK);
    			oss1.clear();
    			std::string* res= new std::string[3];
    			res=acceder(sock,1,hDlg,adr); //<-change de répertoire autant que besoin
    			std::ostringstream oss03;
    			oss03<<"TYPE I\r\n";//RETR DofusPatch_v1_18_0_to_v1_18_1.zip\r\n";//Dofus_v1_18_1.zip\r\n";
    			strcpy_s(TEMP,512,oss03.str().c_str());
    			rep=send(sock, TEMP, (int)strlen(TEMP), 0);
    			regarder(rep);
    			//Sleep(20);
    			oss03.clear();
    			std::ostringstream oss3;
    			oss3<<"PASV\r\n";//RETR DofusPatch_v1_18_0_to_v1_18_1.zip\r\n";//Dofus_v1_18_1.zip\r\n";
    			strcpy_s(TEMP,512,oss3.str().c_str());
    			rep=send(sock, TEMP, (int)strlen(TEMP), 0);
    			regarder(rep);
    			//Sleep(20);
    			if(incomplet) //permet de faire un reste si je fichier existe déjà
    			{
    				std::ostringstream oss6;
    				oss6<<"REST  "<<EcritTotal<<"\r\n";//RETR DofusPatch_v1_18_0_to_v1_18_1.zip\r\n";//Dofus_v1_18_1.zip\r\n";
    				strcpy_s(TEMP,512,oss6.str().c_str());
    				rep=send(sock, TEMP, (int)strlen(TEMP), 0);
    				regarder(rep);
    				//MessageBoxA(hDlg,"PASSEFtp 8","oidcvn",MB_OK);
    				oss6.clear();
    			}
    			//MessageBoxA(hDlg,"PASSEFtp 8","oidcvn",MB_OK);
    			oss3.clear();
    			std::ostringstream oss4;
    			oss4<<"RETR "<<res[2]<</*DofusPatch_v1_18_0_to_v1_18_1.zip*/"\r\n\r\n";//Dofus_v1_18_1.zip\r\n";
    			strcpy_s(TEMP,512,oss4.str().c_str());
    			//MessageBoxA(hDlg,oss4.str().c_str(),"test",MB_OK);
    			rep=send(sock, TEMP, (int)strlen(TEMP), 0);
    			regarder(rep);
    			//Sleep(20);
    			//MessageBoxA(hDlg,"PASSEFtp 9","oidcvn",MB_OK);
    			oss4.clear();
    ...
    J'ai tenté :
    -de mettre des Sleep(), mais le temps de réponse du serveur n'étant pas toujours le même, cela ne sert à rien.
    -de mettre un listen(), mais ca ne change rien.
    Il est impossible, je pense de mettre tout dans la même instruction, car je dois regarder la réponse de chaque appel, et un appel général ne me permettrait pas de les regarder.

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 38
    Par défaut
    La fonction send remet les données à la couche TCP/IP pour distribution, ceci n'implique pas que le serveur les a reçues quand send te rend la main... Il faut donc analyser ce que le serveur te retourne après l'émission d'une commande et suivre le protocole.

    Se connecter puis attendre la réponse
    S'indentifier puis attendre la réponse
    Envoyer le mdp puis attendre la réponse

  3. #3
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2007
    Messages
    387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2007
    Messages : 387
    Par défaut
    Citation Envoyé par afec++
    La fonction send remet les données à la couche TCP/IP pour distribution, ceci n'implique pas que le serveur les a reçues quand send te rend la main... Il faut donc analyser ce que le serveur te retourne après l'émission d'une commande et suivre le protocole.

    Se connecter puis attendre la réponse
    S'indentifier puis attendre la réponse
    Envoyer le mdp puis attendre la réponse
    Je pense que c'est ce qu'est censé faire la fonction regarder (qui regarde si send a renvoyé -1 ou pas).
    Sinon, je ne vois pas quoi faire d'autre.

  4. #4
    Membre averti
    Inscrit en
    Mai 2006
    Messages
    69
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 69
    Par défaut
    Citation Envoyé par PP(Team)
    Je pense que c'est ce qu'est censé faire la fonction regarder (qui regarde si send a renvoyé -1 ou pas).
    Sinon, je ne vois pas quoi faire d'autre.
    Oui ok d'accord mais si send a renvoyé -1 ca fait quoi ? si ta fonction regarder ne fait rien en cas d'echec, c'est normal que ton programme continue, non ?
    Il ne faudrait pas plutot faire un truc genre :

    tant que j'ai pas recu de reponse faire
    envoyer socket
    fin faire

    et continuer apres ton programme ?

    - EDIT - les si n'aiment pas les rait ...

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    38
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 38
    Par défaut
    Citation Envoyé par PP(Team)
    Je pense que c'est ce qu'est censé faire la fonction regarder (qui regarde si send a renvoyé -1 ou pas).
    Sinon, je ne vois pas quoi faire d'autre.
    send retour ne nombre de 'caratères' remis à la couche TCP ce qui ne veut pas dire que ces caractères ont été délivrés au serveur.
    La fonction regarder teste uniquement cette valeur mais n'attend pas la réponse du serveur.

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Février 2005
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 42
    Par défaut
    Ta fonction regarder fait elle un "recv" en plus de vérifier le retour de "send" ?

    Si oui alors c'est, peut être que ton socket est en mode non-bloquant (mais par défaut, il est bloquant).

    Sinon alors tu devrais faire envoyer par le serveur un "accusé" (que tu réceptionne avec recv) pour que le client ne fasse pas tous les send "à la volée".

  7. #7
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2007
    Messages
    387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2007
    Messages : 387
    Par défaut
    Suites aux différentes aides, j'ai fais une autre solution :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    static void regarder(int rep)
    {
    	bool b=false;
    	while(!b)
    	{
    		if(rep==-1)
    		{
    			Mes("Erreur send()");
    			exit(0);
    		}
    		else
    			if(rep>0) //renvoie deu nombre de bits effectivements recus
    			{
    				b=true;
    			}
    	}
    }
    Mais le problème est qu'apparemment, le serveur renvoie des valeurs "intermédaires", car ca quitte beaucoup trop vite.

  8. #8
    Membre éclairé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Janvier 2007
    Messages
    387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2007
    Messages : 387
    Par défaut
    Citation Envoyé par Batoche
    Ta fonction regarder fait elle un "recv" en plus de vérifier le retour de "send" ?

    Si oui alors c'est, peut être que ton socket est en mode non-bloquant (mais par défaut, il est bloquant).

    Sinon alors tu devrais faire envoyer par le serveur un "accusé" (que tu réceptionne avec recv) pour que le client ne fasse pas tous les send "à la volée".
    Non non, la fonction fait des send pour envoyer la requête au serveur uniquement.
    La solution de l'accusé est intéressante...

Discussions similaires

  1. Réponses: 3
    Dernier message: 03/08/2009, 08h12
  2. Comment faire pour se connecter à une base de données ?
    Par petitclem dans le forum C++Builder
    Réponses: 10
    Dernier message: 03/09/2008, 10h52
  3. Réponses: 7
    Dernier message: 18/07/2007, 16h40
  4. comment faire attendre l'internaute?
    Par sam01 dans le forum Langage
    Réponses: 1
    Dernier message: 04/05/2006, 09h13
  5. première connection : comment faire?
    Par jaimepasteevy dans le forum Installation
    Réponses: 2
    Dernier message: 08/12/2003, 12h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo