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