1

This is primarily Node.js question but it likely requires to be familiar with Win32 API and named pipes.

Node.js supports Windows named pipes for IPC connections. Here's an example:

// server.js
const server = require('net').createServer((socket) => {
    socket.write('test\n');
    socket.on('end', () => {
        server.close();
    });
});

server.listen('\\\\.\\\pipe\\\WinUAE');

It doesn't work when named pipe is connected by third-party client written in C++, this results in ERROR_INVALID_PARAMETER (code 87) error:

Connected to '\.\pipe\WinUAE'

SetNamedPipeHandleState failed err=87

And the snippet that causes the problem:

mode = PIPE_READMODE_MESSAGE;
if (!SetNamedPipeHandleState(p, &mode, NULL, NULL)) {
printf("SetNamedPipeHandleState failed err=%d\n", GetLastError());
return 0;
}

Client binary can be downloaded here, and the mirror in case of hosting problems.

I assume the problem is that Node.js doesn't fully support Windows named pipes and cannot be used for IPC in cases that demand first-class support like this one.

Is Node.js not suitable for IPC with such process? What is going on here under the hood?

4
  • PIPE_READMODE_MESSAGE - The function fails if this flag is specified for a byte-type pipe. - think you create exactly byte-type pipe - PIPE_TYPE_MESSAGE is not set. anyway your client code not need try set PIPE_READMODE_MESSAGE Commented Jul 22, 2020 at 18:32
  • and as separate note, how you implement client..i be say not best way. not need separate thread, threadmode_?, etc. need open pipe in asynchronous mode, always read after open and until close. write at any time when need Commented Jul 22, 2020 at 18:39
  • I worked on the assumption I have no control over client code, it belongs to the third party. Thanks for pointing this out, I'm studying what are the quirks of pipe server and client working together. Commented Jul 23, 2020 at 8:11
  • 1
    really any correct server and client code working together. most power and clean logic will be if use asynchronous pipe. when you can read and write to it in concurrent, without any hangs. concrete client code have mistake - try set PIPE_READMODE_MESSAGE Commented Jul 23, 2020 at 10:16

1 Answer 1

3

This is primarily Node.js question

No, I can reproduce it with C++, creating namepipe with PIPE_TYPE_BYTE type(this is the default type).

As @RbMm pointed out, according to the SetNamedPipeHandleState:

PIPE_READMODE_MESSAGE: Data is read from the pipe as a stream of messages. The function fails if this flag is specified for a byte-type pipe.

This is because the type modes must be the same for all instances of a pipe, but PIPE_TYPE_BYTE do not support PIPE_READMODE_MESSAGE mode. CreateNamedPipe:

dwPipeMode

The same type mode must be specified for each instance of the pipe.

PIPE_TYPE_BYTE: Data is written to the pipe as a stream of bytes. This mode cannot be used with PIPE_READMODE_MESSAGE. The pipe does not distinguish bytes written during different write operations.

PIPE_READMODE_MESSAGE: Data is read from the pipe as a stream of messages. This mode can be only used if PIPE_TYPE_MESSAGE is also specified.

As the document Named Pipe Type, Read, and Wait Modes:

To create a byte-type pipe, specify PIPE_TYPE_BYTE or use the default value. The data is written to the pipe as a stream of bytes, and the system does not differentiate between the bytes written in different write operations.

To create a message-type pipe, specify PIPE_TYPE_MESSAGE. The system treats the bytes written in each write operation to the pipe as a message unit. The system always performs write operations on message-type pipes as if write-through mode were enabled.

When specified as PIPE_TYPE_BYTE, the system does not differentiate between the bytes written in different write operations, so the message unit in each write operation is also not able to be differentiated.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the detailed explanation. Differences between byte and message is exactly what I had to deal with for IPC.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.