Named Pipes richtig verwenden...
-
Hi!
Ich hab mir schon ewig viel über pipes durchgelesen aber ich verstehe nicht, wie ich einen blocking-server mit einem nonblocking-client verwende.
Müssen beide seiten FILE_FLAG_OVERLAPPED haben? Und was ist mit PIPE_NOWAIT?JA, alle dies Begriffe werden im MSDN erklärt und ich sitze bestimmt schon zwei ganze Tage davor und bekomme es nicht hin.
Wenn dann mal was funktioniert, übertrage ich das Ganze in eine DLL um zu sehen dass es wieder nicht funktioniert (Error: All pipe instances are busy oder was auch immer).Nun, das möchte ich:
.) Einen blocking server, welcher nur darauf wartet bis Daten ankommen, diese dann ausgibt, und weiter wartet...
.) Einen non-blocking clienten, welcher in einer Schleife einfach nur sendet, ohne Unterbrechung, ohne Warten, ohne hänger, falls der Server hängt...Wie stelle ich das an? Muss ich GetOverlappedResult() verwenden? Muss ich Events verwenden? Muss ich WaitForSingleObject() verwenden? Und die ganzen Flags ... ich versteh es einfach nicht.
Danke im Voraus!
MFG,
Johnny Brown
-
Diese Frage ist absolut überflüssig, weil die MSDN Doku hierzu sogar ein volles Beispiel liefert, das man nutzen kann (dafür braucht man exakt 3 Minuten). Alles ist hier beschrieben was Du fragst:
http://msdn.microsoft.com/en-us/library/aa365603(VS.85).aspx
http://msdn.microsoft.com/en-us/library/aa365592(VS.85).aspx
http://msdn.microsoft.com/en-us/library/aa365588(VS.85).aspxIch würde Dich bitten explizit uzu diesem Beispiel Deine Fragen zu stellen. Dann wird die Diskussion weitaus einfacher.
-
Mhm, ich denke ich habe ein Hauptproblem gelöst. Die Fehlermeldung "Alle Pipeinstanzen sind ausgelastet" kam immer wieder, bis ich den Namen der Pipe änderte.
Aber warum ist das so? Sollte eine Pipe nicht automatisch aufgeräumt werden, nachdem das Programm beendet wurde (Hab einige male den Prozess terminieren müssen, so erkläre ich mir jetzt die Fehlermeldung)?
Ok, anscheinend habe ich es geschafft, mein Vorhaben zu realisieren.
Server:
HANDLE pipeHandle = CreateNamedPipe("\\\\.\\pipe\\test", PIPE_ACCESS_INBOUND, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1, 0, 1024, 0, 0); ConnectNamedPipe(pipeHandle, 0); ... // Und halt abbrechen bei dataRead == 0 while(true) ReadFile(pipeHandle, data, sizeof(data), &dataRead, 0);
Client:
HANDLE pipeHandle = CreateFile("\\\\.\\pipe\\test", GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); unsigned long newMode = PIPE_READMODE_MESSAGE; SetNamedPipeHandleState(pipeHandle, &newMode, 0, 0); ... while(true) { static OVERLAPPED overlapped = { }; // Kommt mir komisch vor, aber nur so geht es WriteFile(pipeHandle, data, sizeof(data), &dataWritten, &overlapped); }
Sieht das soweit gut aus? Funktioniert nämlich, bis auf dass wenn der Client schließt, der Server noch einmal etwas empfängt, aber dataRead gleich 0 ist. Nicht wirklich so schlimm...
Aber mache ich es so richtig oder habe ich nur Glück
-
Ich weiß ja nicht mal ob es überhaupt möglich ist dass der Server synchron, der Client aber asynchron arbeitet... Es funktioniert zwar, aber vielleicht ist es ja undefiniert oder so, deshalb frage ich hier ja!
Einen blocking Server könnte man doch auch asynchron mit events machen, oder etwa nicht? Keine Ahnung!
-
Hallo.
Wenn auf "localhost" unterwegs bist, ist meine Lösung: GLOBAL SHARED MEMORY (+ Mutex).
Gruß
Lars
-
... ist ein MicroController.
-
-
Johnson schrieb:
Ich weiß ja nicht mal ob es überhaupt möglich ist dass der Server synchron, der Client aber asynchron arbeitet... Es funktioniert zwar, aber vielleicht ist es ja undefiniert oder so, deshalb frage ich hier ja!
Einen blocking Server könnte man doch auch asynchron mit events machen, oder etwa nicht? Keine Ahnung!
Ich verstehe nicht was Du meinst.
Was meinst Du hier mit synchron und asynchron? Vergiss mal Sockets und Konsorten. Pipes sind weitaus einfacher und simpler zu nutzen.1. Es geht hier nur um die Schreibvorgänge. D.h. wenn ein Client in die Pipe schreibt, dann kehrt der Vorgang sofort zurück, wenn die Daten geschrieben wurden. Das geht meistens extrem schnell. Es spielt keine Rolle ob die daten verarbeitet wurden.
Overlapped I/O an dieser Stelle macht bei kleinen Blöcken gar keinen Sinn. Die Frage ist, ob der Client auch auf Antwort warten muss, dann ist overlapped I/O vermutlich angesagt.
2. Wenn Du einen Multithreaded Server machst, dann macht Overlapped I/O Sinn, denn, wenn keine Daten anliegen, kehrt das System sofort zurück.
3. Wenn Du Overlapped I/O verwendest, dann solltest Du Dir mal ansehen wie das egth. Dazu solte auch ein Event verwendet werden.
Liegen keine Daten an bekommst Du mit GetLastError ERROR_IO_PENDING.
4. Wenn die Pipe zusammenbricht, dann kehrt ReadFile im Overlapped Mode sofort zurück und GetLastError liefert ERROR_BROKEN_PIPE.