EDIT : nouveau probleme
Bonjour, je continue dans mon exercice sur les tubes nommées ...
Je rapelle la chose :
j'ai un prog "serveur", qui attribue a chaque tuilisateur connu, un pipe a sa création
J'ai un prog client ( qui peut être lancé plusieur fois en meme temps )
et qui doit envoyé/recevoir des info avec le serveur.
J'utilise un seule tube dans la direction Client -> Serveur .
Aucun probleme jusqu'a présent .
Par contre, ma dernière fonction doit être capable d'envoyer des donnée du serveur au clients . Et la je bloque :/ J'ai essayé de plusieur manière différente mais ca en passe pas .
Ce que je pensais faire :
-utiliser le tube principale pour indiquer au server que tel client veux tel information ( ca, ca marche )
- envoyez par le tube personaliser du client, l'information
- lire cette info du coté client .
Mais .... non, il ne veux absolument pas :/
j'utilise les tube nommée en WIN32 ( CreateNamedPipe() ) .
Voici ma fonction principale du serveur, qui attend une requete
Voici une partie de la fonction de traitement des donnée niveau serveur
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 // Fonction permettant au serveur de recevoir et d'envoyez des messages aux clients . void Listen() { std::cout << "Le serveur est actif ... " << std::endl ; // On attend que quelqu'un se connecte for(;;) { // Le buffer qui va recevoir les données CHAR Data[4096]; // Le nombre de bytes lu DWORD BytesRead = 0 ; // On attend qu'un utilisateur fasse une requête BOOL fConnected = ConnectNamedPipe(HandleList["Main"],NULL); // Si il y a des donnée a lire, on les récupère puis les traite . if ( fConnected ) { BOOL fSuccess = ReadFile (HandleList["Main"] , // handle to pipe Data , // buffer to receive data 4096 , // size of buffer &BytesRead, // number of bytes read NULL); // not overlapped I/O Data[BytesRead] = '\0'; FlushFileBuffers(HandleList["Main"]); DisconnectNamedPipe(HandleList["Main"]); } // On traite les données ProcessData(Data); } }
Enfin la fonction appelé par l'utilisateur
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 // Fonction qui traite les demandes utilisateur void ProcessData(std::string Data) { // On découpe notre string Keyword - Argeument std::string Keyword ; std::string Arg ; std::string::size_type pos ; pos = Data.find_first_of(" "); Keyword.insert(0,Data,0,pos); Arg.insert(0,Data,pos+1,Data.size()+1); // Si on a une demande de consultation de mail, on envoie a l'utilisateur ses nouveaux message . if ( Keyword == "GetMail" ) { // Le buffer qui va recevoir les données CHAR Data2[4096] = "voila tes mails" ; // Le nombre de bytes lu DWORD BytesSend = 0 ; std::cout << "Requete de mail de : " << Arg << std::endl ; BOOL fSuccess = WriteFile (HandleList[Arg] , // handle to pipe Data2 , // buffer to receive data 4096 , // size of buffer &BytesSend, // number of bytes read NULL); // not overlapped I/O }
Le hic ? ca bloque, le booléen qui indique si l'écriture c'est bien passé ou pas, lors de la réponse du serveur, est toujours a false ... Donc évidement, aprés, le client attend une réponse qui n'arrive pas, et idle .
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86 // Fonction permettant de consulter sa boite de mail . void MailBox() { // Des paramètre de notre pipe . DWORD dwWrite; char szPipeUpdate[4096]; // Notre message a envoyé std::string Message = "GetMail " + LoginName ; // On attend que le pipe soit libre . WaitNamedPipe("\\\\.\\pipe\\PipeMain",100); // On cré notre HANDLE file . HANDLE hFile = CreateFile("\\\\.\\pipe\\PipeMain", GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL); // On remplie notre buffer avec les données à envoyer strcpy(szPipeUpdate,Message.c_str()); // Si le HANDLE n'a pas été créer . if(hFile == INVALID_HANDLE_VALUE) { std::cerr << "Erreur dans le CreateFile du pipe, niveau client" << std::endl ; } else { // On tente d'envoyez des donnée dans le tube BOOL flg = WriteFile(hFile, szPipeUpdate, strlen(szPipeUpdate), &dwWrite, NULL); // Si ca n'a pas réussi, on envoie un message d'erreur . if (FALSE == flg) { std::cerr << "Erreur dans l'envoie de données" << std::endl ; } // On ferme notre HANDLE CloseHandle(hFile); } // Le nom du pipe . std::string PipeName = "\\\\.\\pipe\\Pipe" ; PipeName += LoginName; size_t Size = PipeName.size() + 1; char * Buffer = new char[Size]; // Copie la chaîne ( passage de const char* en char * ... ) strncpy( Buffer, PipeName.c_str(), Size ); HANDLE hPipe; hPipe = CreateNamedPipe (PipeName.c_str(), PIPE_ACCESS_DUPLEX, // read/write access PIPE_TYPE_MESSAGE | // message type pipe PIPE_READMODE_MESSAGE | // message-read mode PIPE_WAIT, // blocking mode PIPE_UNLIMITED_INSTANCES, // max. instances 4096, // output buffer size 4096, // input buffer size 5000, // client time-out NULL); // no security attribute // On attend que quelqu'un se connecte for(;;) { // Le buffer qui va recevoir les données CHAR Data[4096]; // Le nombre de bytes lu DWORD BytesRead = 0 ; // On attend qu'un utilisateur fasse une requête BOOL fConnected = ConnectNamedPipe(hPipe,NULL); // Si il y a des donnée a lire, on les récupère puis les traite . if ( fConnected ) { BOOL fSuccess = ReadFile (hPipe , // handle to pipe Data , // buffer to receive data 4096 , // size of buffer &BytesRead, // number of bytes read NULL); // not overlapped I/O Data[BytesRead] = '\0'; FlushFileBuffers(hPipe); std::cout << " mail recu !!!" << std::endl ; DisconnectNamedPipe(HandleList["Main"]); } } }
Partager