如何从 Node.js 发送到标准输入并从 C 程序的标准输出接收?
How to send to stdin and receive from stdout of C program from Node.js?
我和一位同事需要连接他的 C 程序和我的 Node.js 脚本。我试图证明使用 stdio 在两者之间传递消息的概念,到目前为止,这个概念还没有被证明!节点脚本在初始化时将可执行文件作为子进程启动,但随后无法发送或接收数据。
我编写了一个非常简单的 C 程序,它可以将在标准输入上接收到的任何内容回显到标准输出。我不是 C 程序员所以希望我没有在 16 行中做任何太令人震惊的事情:p :
stream_echo.c:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define BUFFER_SIZE 255
int main(void) {
char * buffer = calloc(BUFFER_SIZE, 1);
while(fgets(buffer, BUFFER_SIZE, stdin) != NULL) {
//Echo back on stdout:
fprintf(stdout, "echo: %s", buffer);
}
}
并且在控制台中的测试显示它按预期工作:
调用这个可执行文件的node.js脚本如下:
child_stdio.js
(function() {
"use strict";
var jcp = require("child_process").spawn("./stream_echo", [], {
detached: false,
stdio: "pipe"
}),
counter = 0,
timer,
sendData = function() {
console.log("In sendData. Connected: " + jcp.connected);
counter += 1;
jcp.stdin.write("This is data " + counter + "\r\n");
timer = setTimeout(sendData, 2000);
};
//******** STDIN ********
jcp.stdin.on("close", (data) => {
console.log("stdin closed.");
if (timer) {
clearTimeout(timer);
}
});
//******** STDOUT ********
jcp.stdout.on("data", (data) => {
console.log("stdout: " + data);
});
jcp.stdout.on("close", (data) => {
console.log("stdout closed.");
});
//******** STDERR ********
jcp.stderr.on("data", (data) => {
console.log("stderr: " + data);
});
jcp.stderr.on("close", (data) => {
console.log("stderr closed.");
});
//******** PROCESS ********
jcp.on("close", (code, signal) => {
console.log("Child process closed.\nCode: " + code + "\nSignal: " + signal);
});
jcp.on("exit", (code, signal) => {
console.log("Child process exited.\nCode: " + code + "\nSignal: " + signal);
});
jcp.on("disconnect", () => {
console.log("Child process disconnected.");
});
console.log("jcp.pid: " + jcp.pid);
console.log("Connected: " + jcp.connected);
console.log("Calling sendData for the first time....");
sendData();
}());
当我运行此脚本时,多次尝试向子进程发送数据并且没有报告任何错误(尽管进程的connected
属性为假)但也没有收到任何消息。当我终止子进程时,流关闭事件和进程关闭事件被触发,脚本正常终止。
我不明白为什么 connected
是 false 但关闭事件会触发。我觉得这是一个重大线索。
任何人都可以告诉我拖网 Internet 不能多少小时吗?
当 stdout
未连接到终端时,它是块缓冲的。这意味着在缓冲区填满或应用程序终止之前不会刷新输出。
在您的 C 应用程序中的 fprintf
之后添加 fflush(stdout)
。
我和一位同事需要连接他的 C 程序和我的 Node.js 脚本。我试图证明使用 stdio 在两者之间传递消息的概念,到目前为止,这个概念还没有被证明!节点脚本在初始化时将可执行文件作为子进程启动,但随后无法发送或接收数据。
我编写了一个非常简单的 C 程序,它可以将在标准输入上接收到的任何内容回显到标准输出。我不是 C 程序员所以希望我没有在 16 行中做任何太令人震惊的事情:p :
stream_echo.c:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define BUFFER_SIZE 255
int main(void) {
char * buffer = calloc(BUFFER_SIZE, 1);
while(fgets(buffer, BUFFER_SIZE, stdin) != NULL) {
//Echo back on stdout:
fprintf(stdout, "echo: %s", buffer);
}
}
并且在控制台中的测试显示它按预期工作:
调用这个可执行文件的node.js脚本如下:
child_stdio.js
(function() {
"use strict";
var jcp = require("child_process").spawn("./stream_echo", [], {
detached: false,
stdio: "pipe"
}),
counter = 0,
timer,
sendData = function() {
console.log("In sendData. Connected: " + jcp.connected);
counter += 1;
jcp.stdin.write("This is data " + counter + "\r\n");
timer = setTimeout(sendData, 2000);
};
//******** STDIN ********
jcp.stdin.on("close", (data) => {
console.log("stdin closed.");
if (timer) {
clearTimeout(timer);
}
});
//******** STDOUT ********
jcp.stdout.on("data", (data) => {
console.log("stdout: " + data);
});
jcp.stdout.on("close", (data) => {
console.log("stdout closed.");
});
//******** STDERR ********
jcp.stderr.on("data", (data) => {
console.log("stderr: " + data);
});
jcp.stderr.on("close", (data) => {
console.log("stderr closed.");
});
//******** PROCESS ********
jcp.on("close", (code, signal) => {
console.log("Child process closed.\nCode: " + code + "\nSignal: " + signal);
});
jcp.on("exit", (code, signal) => {
console.log("Child process exited.\nCode: " + code + "\nSignal: " + signal);
});
jcp.on("disconnect", () => {
console.log("Child process disconnected.");
});
console.log("jcp.pid: " + jcp.pid);
console.log("Connected: " + jcp.connected);
console.log("Calling sendData for the first time....");
sendData();
}());
当我运行此脚本时,多次尝试向子进程发送数据并且没有报告任何错误(尽管进程的connected
属性为假)但也没有收到任何消息。当我终止子进程时,流关闭事件和进程关闭事件被触发,脚本正常终止。
我不明白为什么 connected
是 false 但关闭事件会触发。我觉得这是一个重大线索。
任何人都可以告诉我拖网 Internet 不能多少小时吗?
当 stdout
未连接到终端时,它是块缓冲的。这意味着在缓冲区填满或应用程序终止之前不会刷新输出。
在您的 C 应用程序中的 fprintf
之后添加 fflush(stdout)
。