写入节点中的文件描述符3



console.log使用process.stdout.write写入文件描述符(fd(1

console.error使用process.stderr.write写入文件描述符(fd(2

如何创建新的文件描述符3?并为此写信?

更新:使用net

import net from 'net'
const example = new net.Socket({ fd: 3, writable: true })
const buffBaby = Buffer.from('meow', 'utf8')
example.write(buffBaby)

我得到这个错误:

错误:ENOTTY:设备的ioctl不合适,uv_pipe_open

我试过这个:

const fs = require('fs');
const fd3 = fs.createWriteStream(null, {fd: 3});
fd3.write("Hello to FD 3!n");

错误:ENXIO:没有这样的设备或地址,写入

我假设您的进程已经考虑到了这样一个FD,否则您将询问如何写入文件或套接字,而不是FD。假设是这样,这将起作用:

const fs = require('fs');
const fd3 = fs.createWriteStream(null, {fd: 3});
fd3.write("Hello to FD 3!n");

这创建了与FD 3相关联的新流,就像process.stdout与FD 1相关联并且process.stderr与FD 2相关联一样。

我假设您的FD是阻塞的(Linux中FD的默认值(。如果由于某种原因它是非阻塞的,那么您需要将其改回阻塞或使用net.Socket

如果你在没有给它一个FD写入的情况下运行该代码,那么可能会发生这样的糟糕情况:

events.js:292
throw er; // Unhandled 'error' event
^
Error: EINVAL: invalid argument, write
Emitted 'error' event on WriteStream instance at:
at emitErrorNT (internal/streams/destroy.js:96:8)
at emitErrorCloseNT (internal/streams/destroy.js:68:3)
at processTicksAndRejections (internal/process/task_queues.js:84:21) {
errno: -22,
code: 'EINVAL',
syscall: 'write'
}
Aborted (core dumped)

或者这个:

events.js:292
throw er; // Unhandled 'error' event
^
Error: EBADF: bad file descriptor, close
Emitted 'error' event on WriteStream instance at:
at emitErrorNT (internal/streams/destroy.js:96:8)
at emitErrorCloseNT (internal/streams/destroy.js:68:3)
at processTicksAndRejections (internal/process/task_queues.js:84:21) {
errno: -9,
code: 'EBADF',
syscall: 'close'
}

如果您确实想从节点打开FD,那么您可以使用任何打开文件的普通方法来完成此操作。在这种情况下,你不能保证FD 3,因为节点内部很有可能已经在使用FD 3,你不能只是从它下面偷出来。

这个问题让我停了下来,因为我没有看到任何POSIX或其他系统调用,你可以选择你想要创建的fd编号,比如socket和open-如果错了,请纠正我,我想在网上澄清。nodejs文档中的套接字选项,它说:

fd:(number(如果指定,请使用给定的文件描述符包装现有套接字,否则将创建一个新套接字。

这意味着它不会在您选择的fd上创建套接字,而是重用现有的套接字,我认为这是为了避免出于性能原因创建新连接或与其他线程或使用者共享连接。

最后,请注意,fd编号在每个进程域或(进程控制块(中是唯一的,也就是说,fd的创建是从3开始递增的,因为0、1和2是保留的,基于此,如果你确信打开连接的正确顺序,你可以预测fd编号,因为每个打开的连接或套接字或文件都会创建一个-如果你不关闭它们

最新更新