【问题标题】:Using named pipe in windows containers (same host)在 Windows 容器中使用命名管道(同一主机)
【发布时间】:2020-01-06 10:20:04
【问题描述】:

我想要 2 个 Windows 容器 - 在同一主机上运行(使用 Windows 10 客户端计算机和用于 Windows 的 docker)通过命名管道(不是匿名管道)进行通信。但是,我无法让它工作。

我的命名管道服务器类是here in GitHub。简而言之,代码来自 Microsoft Docs:

    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();
    }

客户端代码(也来自 Microsoft Docs)在同一个 GitHub repo 中。基本上代码如下:

    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();
    }

整个项目在this GitHub directory

如果我现在在本地机器上运行它,客户端可以访问服务器(我在客户端和服务器中都看到控制台消息)。然后我使用以下 docker 文件将可执行文件放入容器中:

FROM mcr.microsoft.com/dotnet/framework/runtime:4.8
WORKDIR /app
COPY ./bin/release/ ./
ENTRYPOINT ["C:\\app\\Namedpipe.exe"]

现在,在 Windows 10 客户端计算机(使用 Docker for Windows)上,我启动服务器:

docker run -it -v \\.\pipe\helloworld:\\.\pipe\helloworld named-pipe-net-framework:latest

此时,我验证了我的主机中有一个命名管道(名称“helloworld”)(使用 pipelist.exe)。然后我在客户端模式下午餐容器:

docker run -it -v \\.\pipe\helloworld:\\.\pipe\helloworld  named-pipe-net-framework:latest

但是客户端永远无法到达管道(它需要很长时间冻结然后失败)。但是,我已经在客户端容器中安装了一个 powershell(使用 docker exec),并且可以运行 pipelist.exe 并查看命名管道“helloworld”是否可用。但是代码不起作用。谁能给我一些指示为什么这不起作用?

【问题讨论】:

    标签: docker containers ipc named-pipes windows-container


    【解决方案1】:

    我发现只有客户端管道可以从容器内连接到主机上打开的服务器管道。

    只有当我使用 C++ WIN32 API 创建这样的管道时它才起作用(对我来说),在使用 .NET 的 NamedPipeClientStream 时我也遇到了同样的冻结。 在容器中创建服务器管道,无论采用何种技术,都会导致错误,大概是因为它已经被容器中的映射占用了。

    这实际上意味着不能通过命名管道直接连接 2 个容器,因为它们都是客户端管道,它们只能连接到主机上的服务器管道。

    我相信 Windows 中命名管道的映射是通过在容器(服务器管道)和主机(客户端管道)上使用几个额外的管道来实现的,并且消息通过 4 个连接的管道链传输: serverhost-clienthost-servercontainer-clientcontainer.

    我花了几天时间在互联网上搜索相同的信息,但没有运气。几乎所有关于 Windows 容器中命名管道行为的案例都是关于从容器内访问 Docker API。人们甚至会开始怀疑它是否能支持其他东西。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多