Fragen zu named pipes



  • Hallo,

    ich habe mal ein paar Fragen zu named pipes die mir die doku nicht wirklich beantwortet.

    ich habe einen (1) controllthread der auf verbindungen wartet und bei einer neuen verbindung einen workthread (das können schonmal 16 oder mehr werden) startet. Die Clients bleiben dauerhaft mit dem server verbunden und dieser sendet den aktuellen status bei änderungen.

    ich beziehe mich auf diese Beispiel: http://msdn.microsoft.com/en-us/library/aa365588.aspx

    mit CreateNamedPipe erzeuge ich die pipe und mit ConnectNamedPipe warte ich bis ein client sich verbunden hat und starte einen Thread.

    Sehe ich das richtig, dass der workthread das gleiche handle wie der controllthread verwendet? wie kann ich die clientverbindungen unterscheiden?

    Oder muss ich CreateNamedPipe einfach für jeden workthread startet und spare mir den controlthread? Und kann ich mehrer pipes mit dem gleichen Namen erstellen?

    Was ist der Unterschied zwischen PIPE_TYPE_BYTE und PIPE_TYPE_MESSAGES? Irgendwie ist das quasi gar nicht dokumentiert.

    Bei sockets bekommt man ja für jede neue Verbindung ein neues Handle.

    Fragen über Fragen

    Das ihr mich bitte nicht falsch versteht. Ich forste seit ca. 2 Stunden durch google und das msdn... help

    Stefan


  • Mod

    StefanKittel schrieb:

    Hallo,
    ich habe mal ein paar Fragen zu named pipes die mir die doku nicht wirklich beantwortet.

    Doch! Tut sie! 🕶

    StefanKittel schrieb:

    mit CreateNamedPipe erzeuge ich die pipe und mit ConnectNamedPipe warte ich bis ein client sich verbunden hat und starte einen Thread.

    Sehe ich das richtig, dass der workthread das gleiche handle wie der controllthread verwendet? wie kann ich die clientverbindungen unterscheiden?

    CreateNamedPipe erzeugt eine Pipe. Wenn ein Connect mit ConnectNamedPipe erfolgt wird das Handle an den Worker übergeben, der macht was er will damit (und muss es schließen).
    Der Mainthread ruft CloseHandle auf und ruft erneut CreateNamedPipe, erhält ein neues Handle für den nächsten Connect und wartet mit ConnectNamedPipe!

    Klaro?

    StefanKittel schrieb:

    Oder muss ich CreateNamedPipe einfach für jeden workthread startet und spare mir den controlthread? Und kann ich mehrer pipes mit dem gleichen Namen erstellen?

    Ich verstehe nicht was DUmenst. Man kann auf einen Pipe Eingang mehrere Clients verbinden. Das braucht man keine neuen Namen!

    StefanKittel schrieb:

    Was ist der Unterschied zwischen PIPE_TYPE_BYTE und PIPE_TYPE_MESSAGES? Irgendwie ist das quasi gar nicht dokumentiert.

    Doch ist es!
    http://msdn.microsoft.com/en-us/library/aa365605(VS.85).aspx

    MSDN schrieb:

    Type Mode
    The type mode of a pipe determines how data is written to a named pipe. Data can be transmitted through a named pipe as either a stream of bytes or as a stream of messages. The pipe server specifies the pipe type when calling CreateNamedPipe to create an instance of a named pipe. The type modes must be the same for all instances of a pipe.

    To create a byte-type pipe, specify PIPE_TYPE_BYTE or use the default value. The data is written to the pipe as a stream of bytes, and the system does not differentiate between the bytes written in different write operations.

    To create a message-type pipe, specify PIPE_TYPE_MESSAGE. The system treats the bytes written in each write operation to the pipe as a message unit. The system always performs write operations on message-type pipes as if write-through mode were enabled

    1. Bei PIPE_TYPE_BYTE ist die Pipe eben wie ein Datenstream. Also wie eine normal mit CreateFile geöffnete Datei deren Stream man auslesen kann. Nachteil: Man muss wieder ein Protokoll haben!
    2. Ich verwende immer PIPE_TYPE_MESSAGES. Damit hast Du also eine Art Datenblock, der als Ganzes versendet wirdund als Ganzes ankommt. Wenn es also nur um Command-Answer geht ist das simpel mit einem 4KB Buffer zu machen.

    StefanKittel schrieb:

    Das ihr mich bitte nicht falsch versteht. Ich forste seit ca. 2 Stunden durch google und das msdn... help

    Verstehe Dein Problem nicht. Du hast vermutlich das Sample nicht mal zum Laufen gebracht in Verbindung mit dem Client?
    http://msdn.microsoft.com/en-us/library/aa365592(VS.85).aspx



  • Hallo Martin,

    Danke. Ich glaube ich versuche das ganze immer noch gedanklich auf Sockets abzubilden.

    Wenn ich das richtig verstand habe funktioniert das ganze so:

    Ich erzeuge eine Pipe und warte auf eine Verbindung.
    Wenn ein Client sich verbindet, gebe ich die Pipe an den Workerthread, schliesse das Handle und erzeuge mir mit Createpipe ein neues und warte wieder.
    Der Workerthread beendet seine Pipe am Ende.
    Richtig? Ich frage deshalb so deutlich nach, da bei Sockets der "Haupt-"Socket ja immer erhalten bleibt.

    Das Beispiel habe ich zum laufen gebracht, es konnte meine Fragen aber nicht beantworten.

    Das mit den Messages habe ich so schon verstanden.
    Aber:
    - Wer definiert wie wo was eine Message ist oder wie gross sie ist.
    - Wie realisiere ich das beim lesen? ReadFile mit größe 1?
    Ich kann gerade nicht in die doku schauen, da ich beim Kunden sitze.

    Danke für Deine Zeit.

    Stefan


  • Mod

    StefanKittel schrieb:

    Wenn ich das richtig verstand habe funktioniert das ganze so:

    Ich erzeuge eine Pipe und warte auf eine Verbindung.
    Wenn ein Client sich verbindet, gebe ich die Pipe an den Workerthread, schliesse das Handle und erzeuge mir mit Createpipe ein neues und warte wieder.
    Der Workerthread beendet seine Pipe am Ende.
    Richtig?

    Ja! Allerdings wird CreateNamedPipe verwendet!
    Kannst Du alles in dem Sample sehen!
    Du kanst auch en Pipe Handle erneut verwenden wenn ein Client mit DisconnectNamedPipe getrennt wird. Aber dasmacht das Ganze nur kompliziert.

    StefanKittel schrieb:

    Das Beispiel habe ich zum laufen gebracht, es konnte meine Fragen aber nicht beantworten.

    Wieso nicht?
    Da wird es doch genauso gemacht. Schau Dir den Mainthread an!

    StefanKittel schrieb:

    Das mit den Messages habe ich so schon verstanden.
    Aber:
    - Wer definiert wie wo was eine Message ist oder wie gross sie ist.

    Hast Du nicht die Sektion über die Buffergrößen in CreateNamedPipe gelesen.
    Es bleibt Dir überlassen. Die Größen sind "advisory".
    http://msdn.microsoft.com/en-us/library/aa365150(VS.85).aspx

    Ansonsten kannst Du übertragen, was Du willst!

    StefanKittel schrieb:

    - Wie realisiere ich das beim lesen? ReadFile mit größe 1?
    Ich kann gerade nicht in die doku schauen, da ich beim Kunden sitze.

    Verstehe ich nicht. Du liest 1 Byte eben!
    Ich mache das grundsätzlich so, dass ich in den ersten 2/4 bytes die Länge der Nachricht reinpacke. Diese 2/4 Bytes lese und dann einfach den Rest der Nachricht was ich eben noch da ist. (siehe auch ERROR_MORE_DATA)

    Wieso kannst Du nicht nachsehen? Du hast doch Internet, sonst könntest Du hier nicht posten und fragen. 😕



  • Hallo Martin,

    Internet hatte ich schon, aber der Bildschrim hatte nur 640x480 und die Tastatur die 8cm breit war 🙂

    Funktionieren tut das ganze so wie es soll. Das Pipes und Sockets so anders funktionieren iritiert mich immer noch, aber was solls.

    Praktisch macht es aber irgendwie keinen Unterschied ob ich byte oder message verwende. Bei message versucht er ja dies als Packet zu verschicken, bei Byte als Stream. Da ich die Lägne aber eh, wie von Dir vorgeschlagen, in den ersten 4Bytes schicke ist das aber eh egal.

    Ich habe dafür mal meine alten IFF-Includes rausgeholt. Das war mal lange vor XML...

    Danke für Deine/Eure Hilfe

    Stefan


  • Mod

    Wenn Du im Messagemode sowieso arbeitest, dann solltest Du ihn auch verwenden. Der Byte Mode ist komplexer und IMHO minimal langsamer auf der Client Seite. Zudem bekommst Du evtl. schon dann Teile der Nachricht am Client obwohl der Sender diese noch am bereistelen ist.

    BTW: Ich empfinde Named Pipes weitaus simpler und einfacher...



  • ok. Diese Info fehlte mir in dieser Form. Danke.

    Stefan


Anmelden zum Antworten