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.


Anmelden zum Antworten