The name of this is inter-process communication ( IPC, Interprocess Communications ).
It can be done in several ways:
- Sockets
- Named Pipes
- Memory-mapped files
- among others
I'll show you how to do it using Named Pipes, based on this SOEN response , slightly modified to be functional ( because the guy there did not test the answer, but I did).
The example consists of two Console applications communicating, but could be any type of application, that is, it applies perfectly to you.
There are two main classes:
-
PipeServer
: allows serving multiple clients with the same named pipe
-
PipeClient
: allows you to connect to a named pipe server
The example consists of exchanging numbers between the client and the server, each part incrementing the number with a random number from 0 to 10 and sending it back to the other side.
You can start the server, and then start multiple clients. The server will print on the screen the numbers it receives and send to customers, and customers will do the same.
NamedPipesServer.csproj
PipeServer.cs
usingSystem;usingSystem.IO.Pipes;usingSystem.Threading;namespaceNamedPipesServer{publicclassPipeServer{privateThreadrunningThread;privatevolatileboolpareAssimQuePossivel;publicstringPipeName{get;privateset;}publicPipeServer(stringpipeName){this.PipeName=pipeName;}privatevoidServerLoop(){while(!this.pareAssimQuePossivel)this.ProcessNextClient();}publicvoidIniciar(){this.runningThread=newThread(this.ServerLoop);this.runningThread.Start();}publicvoidParar(){this.pareAssimQuePossivel=true;}publicvoidAbortar(){this.runningThread.Abort();}privatevoidProcessClientThread(objecto){using(varpipeStream=(NamedPipeServerStream)o){try{this.OnProcessClient(pipeStream);}finally{pipeStream.WaitForPipeDrain();if(pipeStream.IsConnected)pipeStream.Disconnect();}}}publiceventProcessClientProcessClient;protectedvirtualvoidOnProcessClient(NamedPipeServerStreamo){if(this.ProcessClient!=null)this.ProcessClient(this,o);}privatevoidProcessNextClient(){try{varpipeStream=newNamedPipeServerStream(this.PipeName,PipeDirection.InOut,-1);pipeStream.WaitForConnection();//Spawnanewthreadforeachrequestandcontinuewaitingvart=newThread(this.ProcessClientThread);t.Start(pipeStream);}catch(Exceptione){//Iftherearenomoreavailableconnections//(254isinusealready)thenjust//keeploopinguntiloneisavailable}}publicvoidEsperarAteDesconectar(){if(this.runningThread!=null)this.runningThread.Join();}}publicdelegatevoidProcessClient(PipeServersender,NamedPipeServerStreamstream);}
Program.cs
usingSystem;usingSystem.IO;usingSystem.IO.Pipes;usingSystem.Threading;namespaceNamedPipesServer{staticclassProgram{staticvoidMain(string[]args){varserver=newPipeServer("MeuNamedPipe");
server.ProcessClient += ProcessClient;
server.Iniciar();
server.EsperarAteDesconectar();
}
private static volatile int number;
private static ConsoleColor[] colors = new []
{
ConsoleColor.Blue,
ConsoleColor.Cyan,
ConsoleColor.Green,
ConsoleColor.Magenta,
ConsoleColor.Red,
ConsoleColor.White,
ConsoleColor.Yellow,
};
private static object locker = new object();
private static void ProcessClient(PipeServer sender, NamedPipeServerStream stream)
{
var reader = new StreamReader(stream);
var writer = new StreamWriter(stream);
var random = new Random();
var color = colors[Interlocked.Increment(ref number)];
writer.WriteLine(color);
int num = 0;
while (true)
{
num += random.Next(10);
lock (locker)
{
Console.ForegroundColor = color;
Console.WriteLine("Send: " + num);
}
writer.WriteLine(num);
writer.Flush();
stream.WaitForPipeDrain();
Thread.Sleep(1000);
var recv = reader.ReadLine();
lock (locker)
{
Console.ForegroundColor = color;
Console.WriteLine("Received: " + recv);
}
var recvNum = int.Parse(recv);
num = recvNum;
Thread.Sleep(1000);
}
}
}
}
NamedPipeClient.csproj
-
PipeClient.cs
using System;
using System.IO.Pipes;
using System.Threading;
namespace NamedPipeClient
{
public class PipeClient
{
private Thread runningThread;
private volatile bool pareAssimQuePossivel;
public string PipeName { get; private set; }
public bool PareAssimQuePossivel
{
get { return this.pareAssimQuePossivel; }
}
public PipeClient(string pipeName)
{
this.PipeName = pipeName;
}
private void ClientProcessorThread()
{
while (true)
{
try
{
using (var pipeStream = new NamedPipeClientStream(".", this.PipeName, PipeDirection.InOut))
{
pipeStream.Connect(10000);
try
{
this.OnProcessServer(pipeStream);
}
finally
{
pipeStream.WaitForPipeDrain();
}
}
}
catch (Exception e)
{
// If there are no more available connections
// (254 is in use already) then just
// keep looping until one is available
}
}
}
public void Iniciar()
{
this.runningThread = new Thread(this.ClientProcessorThread);
this.runningThread.Start();
}
public void Parar()
{
this.pareAssimQuePossivel = true;
}
public void Abortar()
{
this.runningThread.Abort();
}
public event ProcessServer ProcessServer;
protected virtual void OnProcessServer(NamedPipeClientStream o)
{
if (this.ProcessServer != null)
this.ProcessServer(this, o);
}
public void EsperarAteDesconectar()
{
if (this.runningThread != null)
this.runningThread.Join();
}
}
public delegate void ProcessServer(PipeClient sender, NamedPipeClientStream stream);
}
-
Program.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Pipes;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace NamedPipeClient
{
static class Program
{
static void Main(string[] args)
{
var client = new PipeClient("MeuNamedPipe");
client.ProcessServer += ProcessServer;
client.Iniciar();
client.EsperarAteDesconectar();
}
private static void ProcessServer(PipeClient sender, NamedPipeClientStream stream)
{
var reader = new StreamReader(stream);
var writer = new StreamWriter(stream);
var random = new Random();
var colorStr = reader.ReadLine();
var color = (ConsoleColor)Enum.Parse(typeof(ConsoleColor), colorStr);
Console.ForegroundColor = color;
int num;
while (true)
{
var recv = reader.ReadLine();
Console.WriteLine("Received: " + recv);
var recvNum = int.Parse(recv);
num = recvNum;
Thread.Sleep(1000);
num += random.Next(10);
Console.WriteLine("Send: " + num);
writer.WriteLine(num);
writer.Flush();
stream.WaitForPipeDrain();
Thread.Sleep(1000);
}
}
}
}