Bonjour,

J'ai un problème similaire à une approche multi - client.
un service (server) tourne tout le temps et une ou plusieurs GUI (client) doivent communiquer avec le serveur.

Le serveur à un nom unique et chaque client définit son nom dynamiquement. le server à la possibilité d'avori ce nom.

le server et chaque client se chargent de creer un pipe en INBOUND et le lit quand un un message arrive.

Attention ce n'est pas du Dupleix car le server doit pouvoir parler avec chaque client de manière asynchrone and allant chercher leur pipe.


Le code est parfaitement adaptable en server et client dans le principe. et Le voici mais ça ne marche pas :


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
59
60
61
62
63
void DispatcherRoot::initPlatformSpecificData()
{
	mPlatformSpecificData = new DispatcherRootPlateformSpecificData_win();
	((DispatcherRootPlateformSpecificData_win*)mPlatformSpecificData)->dispatcherRoot = this;
	
	CString lPipeName("\\\\.\\pipe\\");
	lPipeName += mName.c_str();
	

HANDLE htest = 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 
	
/// creation d'un event pour utiliser RegisterWaitForSingleObject

	OVERLAPPED ovr;
	 HANDLE h = CreateEvent(
		NULL,    // default security attribute 
        TRUE,   // manual-reset event 
        FALSE,   // initial state = signaled 
        NULL);  // unnamed event object 
		
	
	 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(htest,&ovr);
		((DispatcherRootPlateformSpecificData_win*)mPlatformSpecificData)->hPipe = htest;

	HANDLE hWait;
bool test2 = RegisterWaitForSingleObject(
		&hWait,
		((DispatcherRootPlateformSpecificData_win*)mPlatformSpecificData)->hPipe,
		(WAITORTIMERCALLBACK)callback,
		mPlatformSpecificData,
		INFINITE,
		WT_EXECUTEDEFAULT);
}

void DispatcherRoot::finalizePlatformSpecificData()
{
	DisconnectNamedPipe(((DispatcherRootPlateformSpecificData_win*)mPlatformSpecificData)->hPipe); 
	CloseHandle(((DispatcherRootPlateformSpecificData_win*)mPlatformSpecificData)->hPipe); 
	delete mPlatformSpecificData;
}
Code of the callback send and receive functions

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
59
60
void* callback(void* aArg)
{
	DispatcherRootPlateformSpecificData_win* lPlatformSpecificData = (DispatcherRootPlateformSpecificData_win*)aArg;
	ReadFromPipe(lPlatformSpecificData);
	return NULL;
}
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 
			0,			// 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("CreatePipe 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);
}


void ReadFromPipe(DispatcherRootPlateformSpecificData_win* aPlatformData)
{
	//Read client requests from the pipe. 
	BOOL lStatus= ReadFileEx( 
		((DispatcherRootPlateformSpecificData_win*)aPlatformData)->hPipe,     // handle to the pipe created in Initialization
		((DispatcherRootPlateformSpecificData_win*)aPlatformData)->buffer,    // buffer to receive data in the same structure
		BUFSIZE, // size of buffer 
		(LPOVERLAPPED)aPlatformData,
		(LPOVERLAPPED_COMPLETION_ROUTINE) CompletedReadRoutine);
	if( !lStatus )
		LCTrace("could not setup read completion routine %d",GetLastError());
}

VOID WINAPI CompletedReadRoutine(DWORD dwErr, DWORD cbBytesRead, LPOVERLAPPED aOverlap) 
{
	DispatcherRootPlateformSpecificData_win* lPlatformData = (DispatcherRootPlateformSpecificData_win*) aOverlap;

	if ((dwErr == 0) && (cbBytesRead != 0))
	{
		std::string lData = lPlatformData->buffer;
		lPlatformData->dispatcherRoot->receivedData(lData,NULL);
	}
}

Quand je lance mon client et que j'écris par la fonction sendData mon server ne reçoit rien, il n'est pas alerter par l'écriture côté client.

j'ai éssyé sans l'overlapped ça roule mais le server est bien entendu bloqué sur une attente d'écriture côté client. et ce n'est pas ce que je veux.


Merci de m'aider les gars je suis bloqué

Robux