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 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
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 : 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
Partager