Node.js,dgram.setBroadcast(标志)由于“EBADF”
我正在使用Node.js 0.6.9,并试图发送数据报广播包。 码:
var sys = require('util'); var net = require('net'); var dgram = require('dgram'); var message = new Buffer('message'); var client = dgram.createSocket("udp4"); client.setBroadcast(true); client.send(message, 0, message.length, 8282, "192.168.1.255", function(err, bytes) { client.close(); });
运行代码:
$ node test.js node.js:201 throw e; // process.nextTick error, or 'error' event on first tick ^ Error: setBroadcast EBADF at errnoException (dgram.js:352:11) at Socket.setBroadcast (dgram.js:227:11) at Object.<anonymous> (/home/letharion/tmp/collision/hello.js:25:8) at Module._compile (module.js:444:26) at Object..js (module.js:462:10) at Module.load (module.js:351:32) at Function._load (module.js:310:12) at Array.0 (module.js:482:10) at EventEmitter._tickCallback (node.js:192:41)
一些使用Googlesearch显示 “EBADF”表示“套接字参数不是有效的文件描述符”。 但是我对这个问题不够了解。
首先,你对Stacktrace的格式有一定的理解,所以让我们先澄清一下,然后再看看这里出现的实际错误。
node.js Stacktrace的格式
node.js:201 throw e; // process.nextTick error, or 'error' event on first tick
这部分只是内部NodeJS逻辑阻塞的位置,并且输出如下错误:
实际的错误堆栈跟踪如下所示,它首先显示callstack中最深的位置,因此在堆栈跟踪中向下 ,将您带入调用层次,最终引导您到代码中的一切开始。
Error: setBroadcast EBADF at errnoException (dgram.js:352:11) at Socket.setBroadcast (dgram.js:227:11) at Object.<anonymous> (/home/letharion/tmp/collision/hello.js:25:8) at Module._compile (module.js:444:26) at Object..js (module.js:462:10) at Module.load (module.js:351:32) at Function._load (module.js:310:12) at Array.0 (module.js:482:10) at EventEmitter._tickCallback (node.js:192:41)
首先,它dgram.js on line 352
失败了, dgram.js
是一个抽象“低级”代码的内部node.js模块。 第352
是一个包含抛出错误的通用逻辑的函数。
它dgram.js in line 227
调用,如果检查失败,则将调用封装到包装的本地UDP套接字setBroadcast
方法中。
hello.js
上一层,我们用hello.js
client.setBroadcast(true);
结束第25
行的hello.js
文件client.setBroadcast(true);
呼叫。
其余的是由hello.js
文件的初始加载导致的更多的node.js代码。
实际的错误
node.js在这里包装的本地代码抛出的错误是EBADF
和UDP
一起查找,给了我们:
EBADF The socket argument is not a valid file descriptor.
通过进一步深入到node.js的兔子洞,我们最终在udp包装器中 ,它包装了实际C实现的uv包装器,我们在uv包装器中find:
/* * Set broadcast on or off * * Arguments: * handle UDP handle. Should have been initialized with * `uv_udp_init`. * on 1 for on, 0 for off * * Returns: * 0 on success, -1 on error. */
引导我们得出你的套接字尚未初始化的结论。
最后,通过client.bind(8000)
绑定套接字修复了缺less的初始化,并使程序运行。
应该在'聆听'事件上调用'setBroadcast'方法:
var socket = dgram.createSocket('udp4'); socket.on('listening', function(){ socket.setBroadcast(true); }); socket.bind(8000);
好像文件描述符只是在绑定或发送时创build的,而且在setBroadcast之前是必需的。 在设置广播之前,您可以调用client.bind()
带任何参数的client.bind()
绑定到随机端口。 不要担心使用随机端口,因为无论如何,使用client.send
时都是“懒惰地”完成的。
var sys = require('util'); var net = require('net'); var dgram = require('dgram'); var message = new Buffer('message'); var client = dgram.createSocket("udp4"); client.bind(); client.setBroadcast(true); client.send(message, 0, message.length, 8282, "192.168.1.255", function(err, bytes) { client.close(); });