René Nyffenegger's collection of things on the web | |
René Nyffenegger on Oracle - Most wanted - Feedback
- Follow @renenyffenegger
|
FIFO / Named Pipes | ||
Das grosse Problem von Pipes ist, dass zwei
Prozesse, die nicht in einer Eltern Kind Beziehung stehen, nicht
mitteinander kommunizieren können. FIFOs umgehen dies, indem statt
Filedescriptoren Namen für die Endpunkte verwendet werden.
Unter Unix
Eine Named Pipe namens aPipe erstellen:
mknod aPipe p
mknod ist für System V4, BSD: /etc/mkfifo
Aus der Pipe lesen:
while true; do cat aPipe; done
In die Pipe schreiben:
echo hallo du da > aPipe echo wie geht es denn > aPipe Unter NT
Dieses Beispiel demonstriert einen Ping Pong Chat. Ping Pong darum, weil derjenige, der
das letzte Wort gesendet hat, blockiert ist, bis der andere wieder ein Wort gesendet hat.
Dass nur ein Wort gesendet werden kann, ist eine weitere Beschränkung, um das Beispiel möglichst
einfach zu halten.
Der Client#include <windows.h> #include <process.h> #include <stdio.h> #include <sstream> #include <iostream> using namespace std; int main(int argc, char* argv[]) { if (argc != 2) { cout << "Client <name>"; return 0; } stringstream nameOfPipe; nameOfPipe<< "\\\\.\pipe\\" << argv[1]; HANDLE hPipe = CreateFile(nameOfPipe.str().c_str(), GENERIC_WRITE | GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL); if(INVALID_HANDLE_VALUE == hPipe) { cout << "Konnte Pipe nicht ffnen" << endl; return 0; } DWORD nofRead, nofWritten; string ans; char bufIn [1000]; while (1) { // Eingabe einlesen... // (Beschraenkung: nur ein Wort) cout << "?" << flush; cin >> ans; // .. und sie senden WriteFile(hPipe,ans.c_str(),ans.length(),&nofWritten,0); ReadFile(hPipe, bufIn, sizeof(bufIn), &nofRead, NULL); bufIn[nofRead]=0; cout << ">" << bufIn << endl; } return 0; } Der Server#include <windows.h> #include <process.h> #include <stdio.h> #include <sstream> #include <iostream> using namespace std; int main(int argc, char* argv[]) { if (argc != 2) { cout << "Server <name>"; return 0; } stringstream nameOfPipe; nameOfPipe << "\\\\.\pipe\\" << argv[1]; char bufIn [1000]; HANDLE hPipe = CreateNamedPipe(nameOfPipe.str().c_str(), PIPE_ACCESS_DUPLEX, // Beide Richtungen PIPE_TYPE_BYTE | PIPE_WAIT, 1, 0,0, // Hoechstens eine Verbindung, // keine Buffer 0, // Timeout in Millisekunden NULL); // Sicherheitsdesk if(INVALID_HANDLE_VALUE == hPipe) { cout << "Konnte Pipe nicht ffnen" << endl; return 0; } // Auf eine Verbindung warten ConnectNamedPipe( hPipe, 0); DWORD nofRead, nofWritten; string ans; while (1) { ReadFile( hPipe, bufIn, sizeof(bufIn), &nofRead, NULL); bufIn[nofRead]=0; cout << ">" << bufIn << endl; // Eingabe einlesen.... // (Beschraenkung: nur ein Wort) cout << "?" << flush; cin >> ans; // ...und senden WriteFile(hPipe,ans.c_str(),ans.length(),&nofWritten,0); } return 0; } |