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

Windows Discussion :

Approche multiclient en Pipe pour expert!


Sujet :

Windows

  1. #1
    Nouveau membre du Club
    Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2007
    Messages : 55
    Points : 30
    Points
    30
    Par défaut Approche multiclient en Pipe pour expert!
    Bonjour voici mon problème

    J'utilise des pipe pour communiquer entre processus, chaque processus crée un pipe. Ce pipe est en INBOUND. le processus qui l'a crée peut seulement lire et les autre y écrire.

    Quand un processus A veut parler à un processus B il appel l'instance du pipe du procces B et écrie dessus. à ce moment là le processus sait qu'il doit lire grâce à des evenement.

    Je crée le pipe d'un processus par la fonction CreateNamedPipe et j'appel puis j'écris sur le pipe d'un autre processus par les fonction :
    1/ CreateFile
    2/ WriteFile

    J'ai un processus à qui tout les autre doivent parler. je l'appel le serveur les autres sont clients.

    Quand le premier client parle au serveur ça fonctionne très bien mais le deuxième n'arrive pas à écrire. CreateFIle ne marche pas.

    Voici le code :

    ///////////////////
    Initialisation et création du pipe
    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
    58
    
    void DispatcherRoot::initPlatformSpecificData()
    {
    	mPlatformSpecificData = new DispatcherRootPlateformSpecificData_win();
    	((DispatcherRootPlateformSpecificData_win*)mPlatformSpecificData)->dispatcherRoot = this;
    	
    	CString lPipeName("\\\\.\\pipe\\");
    	lPipeName += mName.c_str();
    
    	HANDLE lPipe = CreateNamedPipe( 
              lPipeName,  // pipe name 
              PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED,         // read access 
              PIPE_TYPE_MESSAGE |          // message type pipe 
              PIPE_READMODE_MESSAGE |      // message-read mode 
              PIPE_WAIT,                 // blocking mode 
              PIPE_UNLIMITED_INSTANCES,    // max. instances  
    		  BUFSIZE, // output buffer size 
              BUFSIZE, // input buffer size 
              0,                           // client time-out 
              NULL);                       // default security attribute 
    
    	
    	OVERLAPPED ovr;
    	 HANDLE h = CreateEvent(
    		NULL,    // default security attribute 
            TRUE,   // manual-reset event 
            FALSE,   // initial state = signaled 
            NULL);// unnamed event object 
    	
    	 ResetEvent(h);
    
    	 if (h == NULL) 
          {
             printf("CreateEvent failed with %d.\n", GetLastError()); 
             return ;
          }
    
    	ovr.hEvent = h;
    
    	//Since the hPipe was created with FILE_FLAG_OVERLAPPED
    	//and lpOverlapped in ConnectNamedPipe is not NULL,
    	//the OVERLAPPED structure should contain a handle to a manual-reset event object.
    	
    	bool test = ConnectNamedPipe(lPipe,&ovr);
    	
    	HANDLE lWait;
    	bool test2 = RegisterWaitForSingleObject(
    		&lWait,
    		h,
    		(WAITORTIMERCALLBACK)callback,
    		mPlatformSpecificData,
    		INFINITE,
    		WT_EXECUTEONLYONCE);
    
    	((DispatcherRootPlateformSpecificData_win*)mPlatformSpecificData)->hPipe = lPipe;
    	((DispatcherRootPlateformSpecificData_win*)mPlatformSpecificData)->hWait = lWait;
    }
    ///////////////////////////
    Finalisation des objets
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void DispatcherRoot::finalizePlatformSpecificData()
    {
    	UnregisterWait(((DispatcherRootPlateformSpecificData_win*)mPlatformSpecificData)->hWait);
    	DisconnectNamedPipe(((DispatcherRootPlateformSpecificData_win*)mPlatformSpecificData)->hPipe); 
    	CloseHandle(((DispatcherRootPlateformSpecificData_win*)mPlatformSpecificData)->hPipe); 
    	delete mPlatformSpecificData;
    }
    ////////////////////
    La call back qui permet d'être en OverLapped
    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
    void* callback(void* aArg)
    {
    	DispatcherRootPlateformSpecificData_win* lPlatformSpecificData = (DispatcherRootPlateformSpecificData_win*)aArg;
    	ReadFromPipe(lPlatformSpecificData);
    	return NULL;
    }
    
    void ReadFromPipe(DispatcherRootPlateformSpecificData_win* aPlatformSpecificData)
    {
    	//Read client requests from the pipe. 
    	DWORD lread;
    	BOOL lStatus= ReadFile( 
    		(aPlatformSpecificData)->hPipe,     // handle to the pipe created in Initialization
    		(aPlatformSpecificData)->buffer,    // buffer to receive data in the same structure
    		BUFSIZE,
    		&lread,// size of buffer 
    		(LPOVERLAPPED)aPlatformSpecificData);
    	if( !lStatus )
    		printf("Could not setup read completion routine %d\n",GetLastError());
    	else 
    	{
    		std::string lData = aPlatformSpecificData->buffer;
    		printf("%s",lData.c_str());
    		aPlatformSpecificData->dispatcherRoot->receivedData(lData,NULL);
    		
    		UnregisterWait((aPlatformSpecificData)->hWait);
    				
    		OVERLAPPED ovr;
    		HANDLE lEvent = CreateEvent(NULL,TRUE,TRUE,NULL);
    		ResetEvent(lEvent);
    		ovr.hEvent = lEvent;
    		
    		ConnectNamedPipe((aPlatformSpecificData)->hPipe,&ovr);
    		
    		RegisterWaitForSingleObject(
    		&((aPlatformSpecificData)->hWait),
    		lEvent,
    		(WAITORTIMERCALLBACK)callback,
    		aPlatformSpecificData,
    		INFINITE,
    		WT_EXECUTEONLYONCE);
    	}
    }
    ///////////////////////////
    Le DEUXIEME "createfile" plante (d'un deuxième processus client)

    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
    
    void DispatcherRoot::sendData(const std::string& aRootName, const std::string& aData,void* aPlatformData)
    {
    	CString lPipeName("\\\\.\\pipe\\");
    	lPipeName += aRootName.c_str();
    
    	HANDLE lPipe =
    		CreateFile(
    			lPipeName,				// pipe name 
    			GENERIC_WRITE,			// write access 
    			FILE_SHARE_WRITE,						// no sharing 
    			NULL,					// default security attributes
    			OPEN_EXISTING,			// opens existing pipe 
    			FILE_ATTRIBUTE_NORMAL,	// default attributes 
    			0);						// no template file 
    
    	if(lPipe == INVALID_HANDLE_VALUE) 
    	{
    		LCTrace("Create failed"); 
    		return;
    	}
    	else 
    	{
    		DWORD lByteWritten;
    		bool test = WriteFile(lPipe,(LPCTSTR)aData.c_str(),strlen(aData.c_str()),&lByteWritten,0);
    		if(test)
    			LCTrace("data written");
    	}
    	CloseHandle(lPipe);
                 DeleteFIle(lPipeName);
    }

    Quelqu'un a t-il une idée...???

    Robux

  2. #2
    Membre expert Avatar de KiLVaiDeN
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    2 851
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 2 851
    Points : 3 481
    Points
    3 481
    Par défaut
    Salut,

    Peux-tu donner l'erreur (last-error) que tu as ? Je pense que ça peut être utile pour t'aider...

    A+
    K

  3. #3
    Nouveau membre du Club
    Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2007
    Messages : 55
    Points : 30
    Points
    30
    Par défaut
    Salut,

    Dans la fonction sendData j'ai remplacé ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if(lPipe == INVALID_HANDLE_VALUE) 
    	{
    		LCTrace("Create failed"); 
    		return;
    	}
    par ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if(lPipe == INVALID_HANDLE_VALUE) 
    	{
    		LCTrace("Create failed, Last Error :%d",GetLastError()); 
    		return;
    	}
    Je récapitule mon test :

    Lancement du serveur
    lancement du premier client : écriture par la fonction SendData -> OK
    lancement du deuxième client : Je tombe dans LCTrace et j'ai :

    Create failed, last error,231 soit : All pipe instances are busy.

    Je pige pas car le CreateNamedPipe au tout début je lui passe un flag : PIPE_UNLIMITED_INSTANCES donc le deuxième client doit trouver une instance. De plus quand le premier client écrit, le serveur lit (ReadFromPipe) et rend la main.

    thks pour ton aide.

  4. #4
    Membre expert Avatar de KiLVaiDeN
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    2 851
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 2 851
    Points : 3 481
    Points
    3 481
    Par défaut
    Après quelques recherches, j'ai l'impression que ton erreur n'est pas dans ton code.

    Il se peut qu'à la création d'un fichier, ton système lance un processus de type antivirus ou autre, qui prennent la main sur ton file.

    Normalement ton fichier devrait se libérer dès que le traitement antivirus est fini. Pour cela, tu peux alors utiliser ( un peu crado je te l'accorde mais bon.. ) une sorte de timeout avant de lire ton file, ou bien une boucle infinie qui ne sortirait que lorsque le message aurait changé.

    L'avantage, c'est qu'ainsi tu te rendras compte si au moins ton file est libéré ou non...

    A+
    K

  5. #5
    Nouveau membre du Club
    Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2007
    Messages : 55
    Points : 30
    Points
    30
    Par défaut
    Bah déjà ça bloque côté client, car mon deuxième client ne force pas le server à entrer dans la fonction "ReadFromPipe"

    Je vais essayer ce que tu m'a dis.

    Robux

  6. #6
    Nouveau membre du Club
    Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2007
    Messages : 55
    Points : 30
    Points
    30
    Par défaut
    Je pensais qu'un seul pipe pouvait résoudre l'approche multi -client, en effet un client vient ecrit et libère et ainsi de suite mais il semblerait qu'il faut que je crée autant de pipe que de client.


    Qu'en dis tu???

    Robux

  7. #7
    Membre expert Avatar de KiLVaiDeN
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    2 851
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 2 851
    Points : 3 481
    Points
    3 481
    Par défaut
    Plus d'infos disponible ici

    A+
    K

  8. #8
    Nouveau membre du Club
    Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Septembre 2007
    Messages : 55
    Points : 30
    Points
    30
    Par défaut
    Hi,

    Oui c'est un exemple en pipe client de la msdn il y en a d'autres, j'ai aussi vu l'exemple pour le cas OVERLAPPED et finalement j'ai résolu le problème en créant plusieurs instance de pipe pour chaque client.

    Pour ce faire :
    Je crée une première fois mon pipe et j'attend qu'un client vienne écrire.
    à ce moment là le serveur tombe dans la callback grâce à la fonction de synchronisation : le server lit et reset son précedent pipe crée un autre pipe.
    et ainsi de suite.

    Merci de ton aide
    @ plus

    Robux

Discussions similaires

  1. Requête SQL pour expert
    Par frutix dans le forum Langage SQL
    Réponses: 4
    Dernier message: 15/03/2007, 14h02
  2. Réponses: 10
    Dernier message: 27/04/2006, 16h03
  3. différence reload et location + pb très bizarre pour experts
    Par grinder59 dans le forum Général JavaScript
    Réponses: 21
    Dernier message: 09/01/2006, 12h05
  4. probleme SQL pour expert
    Par murlock7 dans le forum Langage SQL
    Réponses: 11
    Dernier message: 16/12/2004, 11h24
  5. Feuille de style avec XML (pour expert !)
    Par jer_the_one dans le forum Composants VCL
    Réponses: 8
    Dernier message: 11/08/2004, 08h48

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