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
时,系统不区分不同写操作写入的字节,因此也无法区分每次写操作中的消息单元。
这主要是 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
时,系统不区分不同写操作写入的字节,因此也无法区分每次写操作中的消息单元。