Named Pipes unter .NET
Frank Dzaebel, erstellt am:
6.2.2008, zuletzt geändert: 6.02.2008
Kategorie:Kommunikation, .NET-Version:3.5, [Download]
Im System.IO.Pipes Namespace gibt es unter anderem die .NET
Klassen: NamedPipeServerStream und NamedPipeClientStream. Hier ein kleines
Windows Forms Beispiel, wie man eine einfache Kommunikation aufbauen kann:

PipeServer.cs:
using System;
using System.IO;
using System.IO.Pipes;
using System.Windows.Forms;
using System.Threading;
class PipeServer
{
TextBox tb;
bool abbruch = false;
/// <summary>Wenn true, wird der Server gestoppt.</summary>
public void Stop()
{
abbruch = true;
}
public void Start(object txtServer)
{
tb = (TextBox)txtServer;
try
{
using (NamedPipeServerStream pipeServer =
new NamedPipeServerStream("TestPipe", PipeDirection.Out))
{
ZeileAnzeigen("NamedPipeServerStream Objekt erzeugt.");
// Warte auf Verbindung von einem Client
ZeileAnzeigen("Warte auf Verbindung von einem Client ...");
pipeServer.WaitForConnection();
ZeileAnzeigen("Client verbunden!");
// Lese die Eingabe des Benutzers und sende es zum Client Prozess.
using (StreamWriter sw = new StreamWriter(pipeServer))
{
while (!abbruch)
{
sw.AutoFlush = true; Application.DoEvents();
ZeileAnzeigen("\r\nBitte Text eingeben, dann Enter drücken ... :");
tb.KeyPress -= new KeyPressEventHandler(tb_KeyPress);
tb.KeyPress += new KeyPressEventHandler(tb_KeyPress);
while (!enterPressed && !abbruch) Thread.Sleep(20);
enterPressed = false;
sw.WriteLine(toWrite);
}
}
}
}
// Ausnahmen behandeln, wenn die Pipe unverbunden oder unbrauchbar ist.
catch (IOException e)
{
ZeileAnzeigen("Fehler: {0}", e.Message);
}
}
bool enterPressed = false;
string toWrite = "";
void tb_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Enter)
{
enterPressed = true;
toWrite = tb.Lines[tb.Lines.Length - 1];
ZeileAnzeigen(". OK, sende: \"" + toWrite + "\"");
}
}
#region Anzeige
private void ZeileAnzeigen(string zeile)
{
tb.Invoke(new UpdateTextCallback(UpdateText),
new object[] { zeile + "\r\n" });
}
private void ZeileAnzeigen(string format, params object[] arguments)
{
tb.Invoke(new UpdateTextCallback(UpdateText),
new object[] { string.Format(format, arguments) });
}
public delegate void UpdateTextCallback(string text);
private void UpdateText(string text)
{
tb.AppendText(text + Environment.NewLine);
Application.DoEvents();
}
#endregion
}
PipeClient.cs:
using System;
using System.IO;
using System.IO.Pipes;
using System.Windows.Forms;
using System.Threading;
class PipeClient
{
TextBox tb;
bool abbruch = false;
/// <summary>Wenn true, wird der Client gestoppt.</summary>
public void Stop()
{
abbruch = true;
}
public void Start(object txtClient)
{
this.tb = (TextBox)txtClient;
using (NamedPipeClientStream pipeClient =
new NamedPipeClientStream(".", "TestPipe", PipeDirection.In))
{
// Verbinde mit der Pipe, oder warte, bis die Pipe verfügbar ist.
ZeileAnzeigen("Versuche die Pipe zu verbinden...");
pipeClient.Connect();
ZeileAnzeigen("Verbunden mit der Pipe.");
ZeileAnzeigen("Es sind gerade {0} PipeServer Instanzen geöffnet.",
pipeClient.NumberOfServerInstances);
using (StreamReader sr = new StreamReader(pipeClient))
{
// Zeigt den gelesenen Text in der TextBox (s.Konstruktor) an.
string temp;
while(!abbruch)
{
temp = sr.ReadLine();
if (temp != "")
ZeileAnzeigen("Empfangen vom Server: '{0}'", temp);
Thread.Sleep(10);
}
}
}
ZeileAnzeigen("Der Client wurde beendet.");
}
#region Anzeige
private void ZeileAnzeigen(string zeile)
{
tb.Invoke(new UpdateTextCallback(UpdateText),
new object[] { zeile + "\r\n" });
}
private void ZeileAnzeigen(string format, params object[] arguments)
{
tb.Invoke(new UpdateTextCallback(UpdateText),
new object[] { string.Format(format, arguments) });
}
public delegate void UpdateTextCallback(string text);
private void UpdateText(string text)
{
tb.AppendText(text + Environment.NewLine);
Application.DoEvents();
}
#endregion