Wie man eine named pipe nicht beschäftigt, nach der client getrennt wurde?
Ich eine named pipe, und ich will die Wiederverwendung der gleichen Leitung auf dem server, ermöglicht den Anschluss von einem anderen client, wenn der ursprüngliche client getrennt wurde. Was ich mache ist:
- erstellt der server eine pipe mit
CreateNamedPipe
- server schreibt Daten mittels
WriteFile
, und wiederholt dies zu tun, solange FehlerERROR_PIPE_LISTENING
zurückgegeben wird (das ist vor jeder client verbunden ist) - - clients eine Verbindung über
CreateFile
- - client liest Daten
- client schließen Rohr Griff mit
CloseHandle
- an dieser Stelle-server wird Fehler
ERROR_NO_DATA
wenn es versucht, weitere Daten zu schreiben - server trennt die Verbindung zwischen dem Rohr mit
DisconnectNamedPipe
, die ich hoffte, Sie sollte es wieder frei - server versucht, die Daten schreiben, wird Fehler
ERROR_PIPE_NOT_CONNECTED
, wiederholt es dies zu tun, bis es keine Fehler - jedoch, wenn ein neuer client eine Verbindung herstellt und versucht
CreateFile
auf das Rohr, wird esERROR_PIPE_BUSY
Daher meine Frage: welche anderen Schritte, die ich tun müssen, um zu trennen-client aus dem Rohr richtig so, dass ein neuer client eine Verbindung herstellen kann?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Experimentieren mit verschiedenen Anrufe, die ich gefunden habe, sind folgende zu funktionieren:
In Reaktion auf
ERROR_PIPE_NOT_CONNECTED
, server durchführen soll:ConnectNamedPipe
macht das Rohr anschließbar (nicht besetzt) wieder.Hinweis: Rohr Zustand ist vorübergehend geändert, um
PIPE_NOWAIT
werden, sonstConnectNamedPipe
Blöcke der server-thread wartet der client unendlich.Andere Lösung könnte wohl sein, schließen Sie den Griff vollständig auf der server-Seite und öffnen Sie Sie erneut.
Das problem ist, dass Sie die linken aus ConnectNamedPipe () sollte immer aufgerufen werden nach CreateNamedPipe() oder DisconnectNamedPipe (), aber vor versuchen jede I/O.
Wenn Sie nicht wollen, zu blockieren, während der Wartezeit für einen client eine Verbindung herstellen, können Sie das Rohr im asynchronen I/O-Modus, in welchem Fall der Anruf zu ConnectNamedPipe() benötigt ein Ereignis-Objekt, das gesetzt wird, wenn ein client eine Verbindung herstellt. Alternativ können Sie PIPE_NOWAIT und rufen Sie ConnectNamedPipe() in regelmäßigen Abständen, bis es gelingt, aber dies ist eine veraltete Funktion und Ihrer Verwendung wird abgeraten. (In den meisten Situationen die Verwendung eines event-Objekts wird auch deutlich effizienter als polling.)
Als Sie entdeckt haben, wird Windows nicht lassen Sie Sie Weg, ohne den Aufruf zu ConnectNamedPipe (), aber da dieses Verhalten ist nicht dokumentiert, es sollte wohl vermieden werden. Ebenso die Tatsache, dass der Aufruf ConnectNamedPipe() ohne zu warten, für Sie erfolgreich zu sein setzt den Zustand der Verbindung des Rohres ist nicht dokumentiert und sollte nicht abhängt.
Wie gewünscht, hier ein paar real-world-code gezeigt werden, dass die server Ende des Rohres. Dieser code stammt aus einem GUI-Anwendung, so dass es verwendet asynchrone I/O, aber es sollte angemerkt werden, dass es spricht nur für einen client gleichzeitig. (Es könnte jedoch sein, die Ausführung in mehreren threads mit nur geringfügigen änderungen.)
(Dieser code wurde herausgegeben nach unten aus dem original zu entfernen Sie überflüssige Logik. Ich habe nicht versucht zu kompilieren die bearbeitete version, so kann es einige geringfügige Probleme).