C# Verständnisfrage zu Named Pipes, senden und "gleichzeitig" empfangen

Mathias09876

Ensign
Registriert
Nov. 2010
Beiträge
235
Hallo zusammen,

ich hätte eine kleine Verständnisfrage zur Kommunikation über Named Pipes.

Und zwar bräuchte ich eine Kommunikation in beide Richtungen, wobei einkommende Daten möglichst schnell verarbeitet werden sollen.
Mein Plan war nun in einem eigenen Thread eine Endlosschleife zu schreiben, in der dauernd mit
Code:
stream.Read()
gelesen wird. Falls das gelesene ungleich string.Empty ist würde ich ein Event auslösen, dass dann bearbeitet wird.
Allerdings würde ich auch gerne hin und wieder über die Pipe etwas senden. Leider beißt sich das mit der Endlosschleife, zumindest funktioniert es bei mir nicht (das Programm bleibt hängen).
Deshalb meine Frage, habe ich einen Denkfehler gemacht bzw. gäbe es eine bessere Möglichkeit, die ich nur gerade nicht sehe?
Mir würde sonst noch einfallen zwei Pipes zu erstellen, eine für jede Richtung aber ist das die beste Lösung?

Grüße
 
Soweit ich dein Problem verstehe MUSST du 2 Pipes nehmen.

Nehmen wir mal an: Thread1 liest die Pipe in einer Endlosschleife, unterbricht dann irgendwann und sendet was auf die selbe Pipe. Woher soll der Thread nun wissen, wann er weiter 'empfangen' kann? Genau, kann er nicht... selbst wenn er auf EOF wartet kann es sein, dass der andere Thread gerade auch wartet. == Deadlock... Und wenn du nach dem 'senden' gleich wieder auf 'empfangen' gehst kann es gut sein, dass der Thread genau die Daten liest, die er gerade gesendet hat.
Das Problem an Threads ist einfach, dass niemand vorhersehen kann, wann genau ein Thread arbeitet, wie lang und wie viel er arbeitet und ob er sich zwischen 2x arbeiten nicht einfach mal ne Stunde Pause gönnt. Du bräuchtest für deinen Fall eine Synchronisation zwischen den Threads, damit sichergestellt ist, dass nicht beide gleichzeitig 'empfangen' und das Programm damit töten.


P.S. ich glaub, du brauchst gar keine Endlosschleife beim Lesen. Soweit ich mich erinnere bekommst du kein EOF Signal, außer irgendwer packt ein EOF in die Pipe.

Als Alternative könntest du statt Pipes evtl. auch Sockets nehmen, aber da treten wieder die selben Probleme auf, außer dass du gezwungen bist 2 Sockets zu nutzen (was natürlich oben genannte Fehler ausschließt). Könnte natürlich noch sein, dass Sockets langsamer arbeiten, weil Netzwerk und so. Aber das sagt dir besser wer anders ;)
 
Zuletzt bearbeitet:
Ja, ok das was Du sagst kling einleuchtend ^^

Noch eine Frage wegen der Endlosschleife bzw. einem EOF,

bisher wars so, wenn ich das stream.Read() aufgerufen hab, dass dann das Programm solang gewartet hat bzw. gehangen ist, bis etwas zu lesen da war. Mit der Endlosschleife würde das Read also nach Datenempfang wieder erneut aufgerufen werden. Damit empfange ich auch alle Daten, die von dem anderen Programm gesendet werden. Oder ist das ein Denkfehler drin?

Danke auf jeden Fall schonmal für Deine Hilfe :)

Gruß
 
Hm. Ich versteh gerad nicht genau was du wissen willst :D

Aber hier ein paar Erläuterungen (möge mich jemand läutern, falls es falsch ist):
stream.Read() liest solang bis es einen EOF findet (wenn niemand was schickt, dann hägt es da für immer). Ich denke mal, du willst eine Art von Nachricht hin und her schicken, dann würde ich einfach jedes Ende einer Nachricht mit einem EOF kennzeichnen. Damit du dann nach der Nachricht wieder eine empfangen kannst, musst du natürlich nochmals stream.Read() aufrufen. (Da hast du die Endlosschleife)
Wahrscheinlich willst du aber auch irgendwie dein Programm beenden können. Das könnte man so lösen: Wenn eine Nachricht einen bestimmten inhalt hat, dann machst du in deiner Endlosschleife ein return oder break oder wie auch immer das in C# heißt :D
 
Darkfirefighter schrieb:
Und zwar bräuchte ich eine Kommunikation in beide Richtungen, wobei einkommende Daten möglichst schnell verarbeitet werden sollen.

Eine Pipe ist nach Definition eine Halbduplex-Verbindung.

A named pipe is a named, one-way or duplex pipe for communication between the pipe server and one or more pipe clients.

Although named pipes give a half-duplex (one-way) flow of data, you can establish full-duplex communication by using two different named pipes, so each named pipe provides the flow of data in one direction. However, you have to be very careful about the order in which these pipes are opened in the client and server, otherwise a deadlock may occur.

http://developers.sun.com/solaris/articles/named_pipes.html#5

Du kannst Daten über eine Pipe nicht gleichzeitig in beide Richtungen versenden, dafür brauchst du mindestens zwei Pipes.

benneque schrieb:
Als Alternative könntest du statt Pipes evtl. auch Sockets nehmen, aber da treten wieder die selben Probleme auf, außer dass du gezwungen bist 2 Sockets zu nutzen (was natürlich oben genannte Fehler ausschließt). Könnte natürlich noch sein, dass Sockets langsamer arbeiten, weil Netzwerk und so.

TCP ist eine Vollduplex-Verbindung, d.h. es reicht eine bestehende Verbindung aus, um Daten in die eine und andere Richtung zu versenden.

Es ist vollkommen richtig das Sockets einen Overhead (Protokolldaten und Kernelbeteiligung über Winsock) generieren und damit potentiell langsamer sind. Das fällt aber nur bei zeitkritischen Anwendungen ins Gewicht.
 
Zuletzt bearbeitet:
@benneque:
Ja genau so wie du es beschrieben hast hatte ich mir das vorgestellt. Allerdings hatte ich nicht an das EOF gedacht ^^
Das mit dem Beenden ist auch ein guter Hinweis, werde das denke ich über ein Flag lösen also quasi while(!flgEnde){...}

@Stefan_Sch:
Stimmt, ich habe mich glaube ich davon blenden lasse, dass es zwar möglich ist Nachrichten in beide Richtungen zu schicken, aber eben nicht gleichzeitig

Danke für Eure Hilfe
 
Falls du mal wieder über Pipes nachdenken solltest, was möglich ist und was nicht:
Stell dir eine Pipe als simple Text-Datei vor!
Man kann reinschreiben und 'lesen', nur dass beim lesen automatsich jedes gelesene Zeichen gelöscht wird.
 

Ähnliche Themen

Zurück
Oben