Problem mit einer Pipe
-
Hallo allerseits!
Die Aufgabe besteht darin, einen Pipeserver zu erstellen, der seine beiden Client-Prozesse selbst startet und dann mit der Übertragung in die Pipe beginnt.
Die Clients sollen die empfangenen Daten nur noch ausgeben.Nun hab ich mehrere Schwierigkeiten.
1.Die Client-Prozesse werden zwar gestartet, aber empfangen nur Müll.
2.Der Server lässt sich nicht per Tastendruck beenden.Ausserdem noch zwei Unklarheiten:
Wird ein Verbindungscheck alla "ConnectNamedPipe()" benötigt, wenn der ChildProcess vom Server aus gestartet wird? Momentan ist er auskommetiert!
Anders wäre es ja, wenn ich den Client manuell starte, dann sehe ich die Notwendigkeit.Woher weiss der Client, wann keine Daten mehr in die Pipe geschoben werden.
Das ganze an dwbytes(siehe Client-Code) zu messen funktioniert nicht.Hoffe jemand hat dazu ein paar Vorschläge.
Dank schonmal,
smooth_op// Pipe Server, der einen Teststring an die Clients weiter leitet #include <iostream> #include <windows.h> #include <stdio.h> // printf() #include <conio.h> //_kbhit() using namespace std; int main() { // Variablen LPCTSTR xPipe = "\\\\.\\NewPipe"; // Name der Pipe DWORD BUFFER = 512; // Datenpuffer LPCTSTR msg = "TESTSTRING"; // zu verschickende Nachricht DWORD dwbytes; // (wrotebytes) Parameter fuer WriteFile() // Pipe erstellen HANDLE hPipe; hPipe = CreateNamedPipe( xPipe, PIPE_ACCESS_OUTBOUND, PIPE_WAIT, 2, BUFFER, BUFFER, NMPWAIT_USE_DEFAULT_WAIT, NULL ); // Client- Prozesse starten // Strukturen fuer 2 Clients STARTUPINFO si[2]; PROCESS_INFORMATION pi[2]; // Client 1 // Struktur initialisieren ZeroMemory( &si[0], sizeof(si[0]) ); si[0].cb = sizeof(si[0]); ZeroMemory( &pi[0], sizeof(pi[0]) ); // Optionen fuer eigenes Konsolenfenster si[0].wShowWindow = SW_SHOW; si[0].dwFlags = STARTF_USESHOWWINDOW; // Start the child process. if( !CreateProcess( NULL, // No module name (use command line). "client1.exe", // Command line. NULL, // Process handle not inheritable. NULL, // Thread handle not inheritable. FALSE, // Set handle inheritance to FALSE. CREATE_NEW_CONSOLE, // Creation flags. NULL, // Use parent's environment block. NULL, // Use parent's starting directory. &si[0], // Pointer to STARTUPINFO structure. &pi[0] ) // Pointer to PROCESS_INFORMATION structure. ) { printf( "CreateProcess failed (%d).\n", GetLastError() ); return -1; } // Client 2 // Struktur initialisieren ZeroMemory( &si[1], sizeof(si[1]) ); si[1].cb = sizeof(si[1]); ZeroMemory( &pi[1], sizeof(pi[1]) ); // Optionen fuer eigenes Konsolenfenster si[1].wShowWindow = SW_SHOW; si[1].dwFlags = STARTF_USESHOWWINDOW; // Start the child process. if( !CreateProcess( NULL, // No module name (use command line). "client2.exe", // Command line. NULL, // Process handle not inheritable. NULL, // Thread handle not inheritable. FALSE, // Set handle inheritance to FALSE. CREATE_NEW_CONSOLE, // creation flags. NULL, // Use parent's environment block. NULL, // Use parent's starting directory. &si[1], // Pointer to STARTUPINFO structure. &pi[1] ) // Pointer to PROCESS_INFORMATION structure. ) { printf( "CreateProcess failed (%d).\n", GetLastError() ); return -1; } // Auf Clients pruefen BOOL fconnect(false); fconnect = ConnectNamedPipe(hPipe,NULL); // if(fconnect) // { cout << "Uebertragung in die Pipe beginnt" << endl; while(true) { // Nachricht in die Pipe schreiben WriteFile(hPipe,msg,strlen(msg),&dwbytes,NULL); // Durch Tastendruck Ende einleiten if(_kbhit()) break; } // } //Ende // Alle Prozesse nacheinander beenden // Wait until child process exits. WaitForSingleObject( pi[0].hProcess, INFINITE ); // Close process and thread handles. CloseHandle( pi[0].hProcess ); CloseHandle( pi[0].hThread ); // Wait until child process exits. WaitForSingleObject( pi[1].hProcess, INFINITE ); // Close process and thread handles. CloseHandle( pi[1].hProcess ); CloseHandle( pi[1].hThread ); // Pipe trennen DisconnectNamedPipe(hPipe); return 0; }// Client1, empfaengt Daten von der Pipe #include <iostream> #include <windows.h> #include <stdio.h> using namespace std; int main() { // Variablen HANDLE hFile; // HANDLE zur Pipe LPCTSTR xPipe = "\\\\.\\NewPipe"; // Name der Pipe char recieve[100]; // char-array fuer empfangene Daten DWORD BUFFER = 512; // Puffer DWORD dwbytes; // Parameter fuer ReadFile() // auf Verbindung mit Server warten BOOL PipeReady(false); PipeReady = WaitNamedPipe(xPipe,NMPWAIT_WAIT_FOREVER); if(PipeReady) { // Pipe oeffnen hFile = CreateFile( xPipe, // file to open GENERIC_READ, // open for reading 0, // share for reading NULL, // default security OPEN_EXISTING, // existing file only 0, // normal file NULL); // no attr. template if (hFile == INVALID_HANDLE_VALUE) { printf("Could not open file (error %d)\n", GetLastError()); return -1; } } cout << " Client beginnt mit der Ausgabe: " << endl; while(true) { // lesen und ausgeben ReadFile(hFile,recieve,BUFFER,&dwbytes,NULL); cout << recieve << endl; //system("PAUSE"); // Datenstrom ende? //if (dwbytes == 0) break; } // HANDLE schliessen CloseHandle(hFile); return 0; }Client 2 ist identisch zu Client 1
-
ok, zwei neue Erkentnisse!
Die Pipe hatte eine falschen Pfad, richtig müsste es heissen:
LPTSTR xPipe = "\\\\.\\pipe\\NEWPIPE";Dank eines Tipps von einem Kommilitonen, hab' ich die zu verschickenden und empfangenden Daten jeweils mittels einer struct realisiert und WriteFile/ReadFile, sowie das cout beim Client darauf verwiesen (Pointer).
Damit funktioniert es, wenn auch nur mit integers.
Womit ich aber immer noch nicht verstehe, was bei meiner ursprünglichen Version schief läuft.