2010-03-03 4 views
8

ich über Named Pipes zu lernen und wurde mit den Named Pipe-Client und -Server Beispiele aus der MSDN doc spielen:Wie erkennt man eine Client-Verbindung mit einem Named Pipe-Client/Server?

Named Pipe Server

Named Pipe Client

ich geändert, um den Client so kann ich geben Sie Nachrichten an die Konsole und lassen Sie sie an den Server senden, wo sie die Nachricht anzeigt und eine Antwort zurücksendet. Im Wesentlichen habe ich eine Schleife hinzugefügt, die nach dem Aufruf von SetNamedPipeHandleState() beginnt und vor dem Aufruf von CloseHandle() endet (d. H. Das Öffnen und Schließen geschieht außerhalb der Schleife, also verwende ich dasselbe Pipe-Handle innerhalb der Schleife).

Meine Frage ist, wenn ich den Client (durch Schließen oder Beenden über den Task-Manager) kill gibt es irgendeine Möglichkeit für die Server-Seite, die Trennung zu erkennen?

Ich habe versucht, mit GetNamedPipeHandleState() in der Hoffnung, dass es Fehler zurückgeben und ein Aufruf von GetLastError() würde ERROR_PIPE_NOT_CONNECTED zurückgeben, aber das war nicht der Fall. Wegen der Art, wie dieser Server eingerichtet ist, musste ich dies in der CompletedReadRoutine-Funktion tun und einen "kontrollierten" Fehler erzeugen. Was ich tat, war, mit einem Haltepunkt auf dem CompletedReadRoutine im Server:

  1. den Server
  2. begann eine Nachricht über den Client (trifft den Haltepunkt in dem Server hier) den Client gestartet
  3. gesendet
  4. Treppenweg bis zum GetNamedPipeHandleState den Client

der Aufruf von GetNamedPipeHandleState getötet() gibt Erfolg Also habe ich den GetLastError() Aufruf nie gemacht. Wenn es zu dem WriteFileEx-Aufruf kommt, schlägt es fehl, und ein Aufruf von GetLastError an diesem Punkt gibt ein ERROR_NO_DATA zurück.

Mit Blick auf die Rohrfunktionen kann ich nichts anderes sehen, das hier helfen könnte. Mir fehlt etwas oder ist ein Client nicht mehr zu trennen.

Die einzige andere Sache, die ich denken kann, sammelt die PIDs der verbindenden Clients (über GetNamedPipeClientProcessId) und Aussperren von Watchdog-Threads, um zu überprüfen, ob sie noch am Leben sind. Wenn ich nur darüber nachdenke, macht das meinen gespaltenen Sinn.

Gibt es eine Möglichkeit, getrennte Clients zu erkennen, wenn Sie Named Pipes verwenden?

Antwort

5

Nicht ReadFile() zurück und Fehler und GetLastError() dann zurück ERROR_BROKEN_PIPE?

+0

Nur wenn ich den Client sehr vorsichtig mit Breakpoints im Server töten, kann ich den Client an einem bestimmten Punkt in der Serverlogik töten. Wenn ich zum Beispiel den Client starte und ihn direkt nach der ersten Verbindung abbringe, aber vor dem ersten Aufruf von ReadFileEx durch den Server, dann bekomme ich ERROR_BROKEN_PIPE. Das Problem ist der Server wartet auf den Aufruf von WaitForSingleObjectEx. Wenn die Client-Seite ausfällt, schreibt oder liest sie nicht von der zuvor mit der Pipe-Instanz verbundenen Pipeline. –

+3

Ich denke nicht wirklich, dass diese Beispiele ein gutes Beispiel dafür sind ... Persönlich hätte ich immer einen überlappenden Lesevorgang, der auf der Pipe läge, auf diese Weise sollten Sie immer eine Benachrichtigung erhalten, wenn der Client weggeht. .. –

+0

Ich höre Sie und stimme zu, dass die Beispiele, die ich habe, nicht das sind, was ich mir ansehen sollte, wie ich die Kommunikation arbeiten lassen möchte. Danke für deinen Beitrag. –

1

ReadFile() + GetLastError() die Arbeit gut machen. Hier ist, wie können sie mit I/O Completion Ports verwendet werden (meine Implementierung ist in Python + ctypes, aber die Idee sollte klar sein):

def connect(): 
    GetQueuedCompletionStatus() 
    receive() 

def receive(): 
    while True: 
     ret_code = ReadFile() 
     if ret_code == 0 and GetLastError() == ERROR_BROKEN_PIPE: 
      # client disconnected 
     GetQueuedCompletionStatus() 

Wir waren für ein Abschlusspaket warten, und wenn ein Client eine Verbindung Wir wechseln zur Hauptschleife. In der Hauptschleife lesen wir die Pipe und überprüfen, ob der Client die Verbindung getrennt hat, indem wir ReadFile() Rückkehrcode und GetLastError() betrachten. Dann werden wir wieder auf ein Completion-Paket warten.

Ein Client kann in jeder Phase getrennt werden. Das Abschlusspaket wird in die Warteschlange gestellt und wir erhalten ERROR_BROKEN_PIPE.

+0

Welche Programmiersprache ist das? Es sieht ein bisschen wie Python aus, aber AFAIK 'winapi' ist nur C, C++, C# und Visual Basic. – wizzwizz4

+0

Ja, das ist Python, aber Sie können winapi-Funktionen mit ctypes library aufrufen. Ein Mechanismus, der dies ermöglicht, heißt FFI: https://en.wikipedia.org/wiki/Foreign_function_interface – wombatonfire