通过命名管道在Windows上访问Docker API

时间:2017-11-15 00:34:25

标签: c# windows docker named-pipes

根据Docker for Windows FAQ,"客户端可以通过命名管道连接到Docker引擎:npipe:////./pipe/docker_engine"

我一直试图通过命名管道连接到API无济于事:

public class DockerNamedPipeTest
{
    private const string PIPE_PATH = "docker_engine";

    public void Test()
    {
        using (NamedPipeClientStream pipeClient = 
            new NamedPipeClientStream(
                ".", 
                PIPE_PATH, 
                PipeDirection.InOut, 
                PipeOptions.WriteThrough, 
                TokenImpersonationLevel.Impersonation))
        {
            pipeClient.Connect(30);                
            Send(pipeClient);
            Receive(pipeClient);
        }
    }

    public void Send(NamedPipeClientStream pipeClient)
    {
        if (pipeClient.IsConnected)
        {
            byte[] buffer = Encoding.UTF8.GetBytes("GET /containers/json");
            pipeClient.Write(buffer, 0, buffer.Length);
            pipeClient.WaitForPipeDrain();
            pipeClient.Flush();
        }
    }

    public void Receive(NamedPipeClientStream pipeClient)
    {
        string result = string.Empty;

        if (pipeClient.IsConnected && pipeClient.CanRead)
        {
            do
            {                    
                byte b = (byte)pipeClient.ReadByte();   //  <-- Hangs here
                result += Convert.ToChar(b).ToString();
            }
            while (!pipeClient.IsMessageComplete);
        }

        Console.WriteLine(result);
    }
}

谁能告诉我我做错了什么?

2 个答案:

答案 0 :(得分:1)

Microsoft的.NET client library for Docker支持命名管道,你看过那个吗?

以下是一个例子:

using Docker.DotNet;
DockerClient client = new DockerClientConfiguration(new Uri("npipe://./pipe/docker_engine"))
 .CreateClient();

答案 1 :(得分:0)

事实证明,答案可以在Docker.DotNet代码的源代码中找到,特别是在名为CloseWrite()的方法中的DockerPipeStream.cs类中:

https://github.com/Microsoft/Docker.DotNet/blob/master/src/Docker.DotNet/DockerPipeStream.cs

// The Docker daemon expects a write of zero bytes to signal the end of writes. Use native
// calls to achieve this since CoreCLR ignores a zero-byte write.

我将此方法应用于我的代码,代码不再挂起。

我现在收到 400 Bad Request ,但至少现在我知道为什么与docker守护程序的通信挂起了。如果Docker for Windows FAQ提到了这个细微差别,那就太棒了。