C++和C#之间如何通过管道进行通信

6
我想通过管道从一个C#应用程序向C++应用程序发送数据。 这是我所做的: 这是C ++客户端:
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>


int _tmain(int argc, _TCHAR* argv[]) {

  HANDLE hFile;
  BOOL flg;
  DWORD dwWrite;
  char szPipeUpdate[200];
  hFile = CreateFile(L"\\\\.\\pipe\\BvrPipe", GENERIC_WRITE,
                             0, NULL, OPEN_EXISTING,
                             0, NULL);

  strcpy(szPipeUpdate,"Data from Named Pipe client for createnamedpipe");
  if(hFile == INVALID_HANDLE_VALUE)
  { 
      DWORD dw = GetLastError();
      printf("CreateFile failed for Named Pipe client\n:" );
  }
  else
  {
      flg = WriteFile(hFile, szPipeUpdate, strlen(szPipeUpdate), &dwWrite, NULL);
      if (FALSE == flg)
      {
         printf("WriteFile failed for Named Pipe client\n");
      }
      else
      {
         printf("WriteFile succeeded for Named Pipe client\n");
      }
      CloseHandle(hFile);
  }
return 0;

这是 C# 服务器的部分代码:}

using System;
using System.IO;
using System.IO.Pipes;
using System.Threading;
namespace PipeApplication1{

class ProgramPipeTest
{

    public void ThreadStartServer()
    {
        // Create a name pipe
        using (NamedPipeServerStream pipeStream = new NamedPipeServerStream("\\\\.\\pipe\\BvrPipe"))
        {
            Console.WriteLine("[Server] Pipe created {0}", pipeStream.GetHashCode());

            // Wait for a connection
            pipeStream.WaitForConnection();
            Console.WriteLine("[Server] Pipe connection established");

            using (StreamReader sr = new StreamReader(pipeStream))
            {
                string temp;
                // We read a line from the pipe and print it together with the current time
                while ((temp = sr.ReadLine()) != null)
                {
                    Console.WriteLine("{0}: {1}", DateTime.Now, temp);
                }
            }
        }

        Console.WriteLine("Connection lost");
    }

    static void Main(string[] args)
    {
        ProgramPipeTest Server = new ProgramPipeTest();

        Thread ServerThread = new Thread(Server.ThreadStartServer);

        ServerThread.Start();

    }
}

当我启动服务器然后启动客户端,从客户端获取的GetLastErrror返回2(系统找不到指定的文件)。
有任何想法吗? 谢谢。
2个回答

6
我猜想,在创建服务器管道时,您不需要使用"\.\Pipe\"前缀。我看到的调用NamedPipeServerStream构造函数的示例只是传递管道名称。例如:
using (NamedPipeServerStream pipeStream = new NamedPipeServerStream("BvrPipe"))

您可以使用SysInternals进程管理器列出打开的管道及其名称,以帮助验证管道是否具有正确的名称。有关详细信息,请参见此问题


我可以确认这一点,我曾在C#和C++之间使用过管道,并且在创建NamedPipeServerStream时没有在管道名称前使用Pipe\前缀。 - Bob Moore
在上面的代码中,直到我们在C++代码中调用CloseHandle在管道句柄上时,数据才会传递给C#服务器。有没有办法在不关闭句柄的情况下进行传递?我也尝试了"FlushFileBuffers"函数,但它没有起作用。 - Raveendra M Pai
@Raveendra 你不能刷新一个套接字。请参考http://stackoverflow.com/questions/12814835/flush-a-socket-in-c获取信息。还可以参考http://www.tangentsoft.net/wskfaq/intermediate.html#packetscheme。 - Andy Johnson

-1
请阅读this以了解管道的实现方式。为什么不使用CreateNamedPipes API调用呢?您将C++端的文件句柄视为普通文件而非管道,因此当它正在寻找管道时,您的C++代码会失败,而实际上它是在尝试从文件中读取数据。

1
可以完全合法地使用CreateFile()打开管道的_client_端。请参阅CreateFile函数的备注部分(http://msdn.microsoft.com/en-us/library/aa363858%28VS.85%29.aspx)。 - Andy Johnson
@andyjohnson: 我不知道你可以这样做...我的错...对于误导性的陈述感到抱歉... :( - t0mm13b

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接