Node.js 命名管道导致 ERROR_INVALID_PARAMETER

Node.js named pipe causes ERROR_INVALID_PARAMETER

这主要是 Node.js 问题,但可能需要熟悉 Win32 API 和命名管道。

Node.js 支持 IPC 连接的 Windows 命名管道。这是一个例子:

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

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

当用 C++ 编写的 third-party client 连接命名管道时,它不起作用,这导致 ERROR_INVALID_PARAMETER(代码 87)错误:

Connected to '\.\pipe\WinUAE'

SetNamedPipeHandleState failed err=87

以及导致问题的snippet

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

如果出现托管问题,可以下载客户端二进制文件here, and the mirror

我假设问题是 Node.js 不完全支持 Windows 命名管道,并且不能用于 IPC 在需要像这样的第一个 class 支持的情况下。

难道Node.js这样的流程不适合IPC吗?引擎盖下发生了什么?

This is primarily Node.js question

不,我可以用 C++ 重现它,用 PIPE_TYPE_BYTE 类型创建名称管道(这是默认类型)。

正如@RbMm 所指出的,根据 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.

这是因为管道的所有实例的类型模式必须相同,但 PIPE_TYPE_BYTE 不支持 PIPE_READMODE_MESSAGE 模式。 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.

作为文件 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.

当指定为PIPE_TYPE_BYTE时,系统不区分不同写操作写入的字节,因此也无法区分每次写操作中的消息单元。