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
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
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); } } ///////////////////////////
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
Partager