Named Pipe C # client cannot connect to C ++ server

I am trying to get a C ++ application so that the C # application knows when a particular action will happen. The way I am trying to do this is with named pipes.

I have set up a named pipe server in a C ++ application which seems to work (a named pipe is created - it appears in the list obtained by PipeList ) and a named pipe client in a C # application where it fails: the first line of C # client code gives : "Pipe handle not installed. Did you call PipeStream InitializeHandle?" error, and line 2 throws the "Path access denied" exception.

Where am I going wrong?

C ++ server code

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 # client code

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

      

+3


source to share


1 answer


The named pipe creation does not have the correct parameters.

First you want to read and write on the pipe, so use the flag: PIPE_ACCESS_DUPLEX

Then you send messages synchronously. Use these flags:PIPE_WAIT | PIPE_TYPE_MESSAGE



Finally, you only allow one instance of this channel per machine. Obviously you need at least 2: one for server side for client. I would just use an unlimited flag:PIPE_UNLIMITED_INSTANCES

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

      

After creating a channel on the server, you should wait for a connection to it before using it: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365146(v=vs.85).aspx

+2


source







All Articles