I want to have 2 windows containers - running on same host (using windows 10 client machine and docker for windows) talking via a named pipe (not anonymous pipes). However, I couldn't make it work.
My named pipe server class is here in GitHub. The code is from Microsoft Docs, in a nutshell:
private void ServerThread(object data)
{
NamedPipeServerStream pipeServer =
new NamedPipeServerStream(this.pipeName, PipeDirection.InOut, numThreads);
int threadId = Thread.CurrentThread.ManagedThreadId;
pipeServer.WaitForConnection();
try
{
StreamString ss = new StreamString(pipeServer);
ss.WriteString("I am the one true server!");
string message = ss.ReadString();
ss.WriteString($"Server message {DateTime.Now.ToLongTimeString()}");
}
catch (IOException e)
{
Console.WriteLine("ERROR: {0}", e.Message);
}
pipeServer.Close();
}
And the client side code (also from Microsoft Docs) is in the same GitHub repo. Essentially the code is following:
private static void RunCore(string ip, string pipeName)
{
NamedPipeClientStream pipeClient =
new NamedPipeClientStream(ip, pipeName,
PipeDirection.InOut, PipeOptions.None,
TokenImpersonationLevel.Impersonation);
pipeClient.Connect();
StreamString ss = new StreamString(pipeClient);
if (ss.ReadString() == "I am the one true server!")
{
ss.WriteString("Message from client " + DateTime.Now.ToString());
Console.Write(ss.ReadString());
}
else
{
Console.WriteLine("Server could not be verified.");
}
pipeClient.Close();
}
The entire project is in this GitHub directory.
If I now run this on my local machine, the client can reach to server (I see console messages both in client and server). Then I put the executable in a container using the following docker file:
FROM mcr.microsoft.com/dotnet/framework/runtime:4.8
WORKDIR /app
COPY ./bin/release/ ./
ENTRYPOINT ["C:\\app\\Namedpipe.exe"]
Now, on windows 10 client machine (with Docker for Windows) I launch the server as:
docker run -it -v \\.\pipe\helloworld:\\.\pipe\helloworld named-pipe-net-framework:latest
At this point, I verified that I have a named pipe (name 'helloworld') in my host (using pipelist.exe). Then I lunch the container in client mode as:
docker run -it -v \\.\pipe\helloworld:\\.\pipe\helloworld named-pipe-net-framework:latest
But the client can never reach to the pipe (it takes a long time freezed and then fails). However, I have lunched a powershell inside the client container (using docker exec) and can run pipelist.exe and see the named pipe 'helloworld' is available. But the code doesn't work. Can anybody give me some pointers why this doesn't work?