【问题标题】:Named Pipe C# client can't connect to C++ server命名管道 C# 客户端无法连接到 C++ 服务器
【发布时间】:2017-09-30 03:50:36
【问题描述】:

我正在尝试让 C++ 应用程序让 C# 应用程序知道特定操作何时发生。我试图做到这一点的方式是通过命名管道。

我已经在 C++ 应用程序上设置了一个命名管道服务器,它似乎正在工作(命名管道被创建 - 它出现在由PipeList 检索的列表中)和一个命名管道客户端在 C# 应用程序上,失败的地方:C# 客户端代码的第一行给出“管道句柄尚未设置。您的 PipeStream 实现是否调用了 InitializeHandle?”错误,第 2 行抛出“访问路径被拒绝”异常。

我哪里错了?

C++ 服务器代码

CString namedPipeName = "\\\\.\\pipe\\TitleChangePipe";

HANDLE pipe = CreateNamedPipe(namedPipeName, PIPE_ACCESS_INBOUND , PIPE_WAIT, 1, 1024, 1024, 120 * 1000, NULL);
if (pipe == INVALID_HANDLE_VALUE) {
    MessageBox(NULL, "Pipe Could Not be Established.", "Error: TCM", MB_ICONERROR);
    return -1;
}

char line[512]; DWORD numRead;

while (true)//just keep doing this
{
    numRead = 1;
    while ((numRead < 10 || numRead > 511) && numRead > 0)
    {
        if (!ReadFile(pipe, line, 512, &numRead, NULL) || numRead < 1) {//Blocking call
            CloseHandle(pipe);                                          //If something went wrong, reset pipe
            pipe = CreateNamedPipe(namedPipeName, PIPE_ACCESS_INBOUND , PIPE_WAIT, 1, 1024, 1024, 120 * 1000, NULL);
            ConnectNamedPipe(pipe, NULL);
            if (pipe == INVALID_HANDLE_VALUE) {
                MessageBox(NULL, "Pipe Could Not be Established.", "Error: TCM", MB_ICONERROR);
                return -1; }
            numRead = 1;
        }
    }
    line[numRead] = '\0';   //Terminate String
}   

CloseHandle(pipe);

C# 客户端代码

var client = new NamedPipeClientStream(".", "TitleChangePipe", PipeDirection.InOut);
client.Connect();
var reader = new StreamReader(client);
var writer = new StreamWriter(client);

while (true)
{
    var input = Console.ReadLine();
    if (String.IsNullOrEmpty(input))
         break;
    writer.WriteLine(input);
    writer.Flush();
    Console.WriteLine(reader.ReadLine());
}

【问题讨论】:

    标签: c# c++ windows ipc named-pipes


    【解决方案1】:

    命名管道创建没有正确的参数。

    首先你想在管道上读写,所以要使用的标志是:PIPE_ACCESS_DUPLEX

    然后,您在此处以同步模式发送消息。使用这些标志:PIPE_WAIT | PIPE_TYPE_MESSAGE

    最后,您在机器上只允许此管道的一个实例。显然,您至少需要 2 个:一个用于服务器,一个用于客户端。我只会使用无限标志:PIPE_UNLIMITED_INSTANCES

    HANDLE pipe = CreateNamedPipe(namedPipeName, PIPE_ACCESS_DUPLEX, \
                                  PIPE_WAIT | PIPE_TYPE_MESSAGE, PIPE_UNLIMITED_INSTANCES, \
                                  1024, 1024, 120 * 1000, NULL);
    

    在服务器中创建管道后,您应该在使用它之前等待该管道上的连接:https://msdn.microsoft.com/en-us/library/windows/desktop/aa365146(v=vs.85).aspx

    【讨论】:

    • 感谢您的回复和解释。我已经更改了CreateNamedPipe 的实例,以便它使用以所述方式建议的变量。据我了解,就在使用它之前等待管道上的连接而言,这就是ConnectNamedPipe 所做的。话虽如此,我不再收到“拒绝访问路径”异常,但我仍然收到“尚未设置管道句柄”。您的 PipeStream 实现是否调用了 InitializeHandle?在客户端代码的第一行。
    • 是的,ConnectNamedPipe 就是这样做的,不仅在循环中使用它!再次检查管道的名称,因为它可能与 '\\pipe' 前缀混淆。我还发现了一个类似的线程:stackoverflow.com/questions/10740479/…。 ;]
    • 谢谢!在你提到的管道创建之后,我也应该在循环之外使用它。现在工作得很好:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-29
    相关资源
    最近更新 更多