net
模块为你提供了异步的网络调用的包装。它同时包含了创建服务器和客户端的函数。你可以通过require('net')
来引入这个模块。
创建一个新的TCP服务器。connectionListener
参数会被自动绑定为connection
事件的监听器。
options
是一个包含下列默认值的对象:
{
allowHalfOpen: false,
pauseOnConnect: false
}
如果allowHalfOpen
是true
,那么当另一端的socket
发送一个FIN
报文时socket
并不会自动发送FIN
报文。socket
变得不可读,但是可写。你需要明确地调用end()
方法。详见end
事件。
如果pauseOnConnect
是true,那么socket
在每一次被连接时会暂停,并且不会读取数据。这允许在进程间被传递的连接不读取任何数据。如果要让一个被暂停的socket
开始读取数据,调用resume()
方法。
以下是一个应答服务器的例子,监听8124端口:
var net = require('net');
var server = net.createServer(function(c) { //'connection' listener
console.log('client connected');
c.on('end', function() {
console.log('client disconnected');
});
c.write('hello\r\n');
c.pipe(c);
});
server.listen(8124, function() { //'listening' listener
console.log('server bound');
});
使用telnet
测试:
telnet localhost 8124
想要监听socket``/tmp/echo.sock
,只需改变倒数第三行:
server.listen('/tmp/echo.sock', function() { //'listening' listener
使用nc
连接一个UNIX domain socket服务器:
nc -U /tmp/echo.sock
工厂函数,返回一个新的net.Socket
实例,并且自动使用提供的options
进行连接。
options
会被同时传递给net.Socket
构造函数和socket.connect
方法。
参数connectListener
将会被立即添加为connect
事件的监听器。
下面是一个上文应答服务器的客户端的例子:
var net = require('net');
var client = net.connect({port: 8124},
function() { //'connect' listener
console.log('connected to server!');
client.write('world!\r\n');
});
client.on('data', function(data) {
console.log(data.toString());
client.end();
});
client.on('end', function() {
console.log('disconnected from server');
});
要连接socket``/tmp/echo.sock
只需要改变第二行为:
var client = net.connect({path: '/tmp/echo.sock'});
工厂函数,返回一个新的net.Socket
实例,并且自动使用指定的端口(port)和主机(host)进行连接。
如果host
被省略,默认为localhost
。
参数connectListener
将会被立即添加为connect
事件的监听器。
工厂函数,返回一个新的unixnet.Socket
实例,并且自动使用提供的路径(path)进行连接。
参数connectListener
将会被立即添加为connect
事件的监听器。
这个类用于创建一个TCP或本地服务器。
开始从指定端口和主机名接收连接。如果省略主机名,那么如果IPv6可用,服务器会接受从任何IPv6地址(::)来的链接,否则为任何IPv4地址(0.0.0.0)。如果端口为0那么将会为其设置一个随机端口。
积压量backlog
是连接等待队列的最大长度。实际长度由你的操作系统的sysctl
设置决定(如linux中的tcp_max_syn_backlog
和somaxconn
)。这个参数的默认值是511(不是512)。
这个函数式异步的。当服务器绑定了指定端口后,listening
事件将会被触发。最后一个参数callback
将会被添加为listening
事件的监听器。
有些用户可能遇到的情况是收到EADDRINUSE
错误。这意味着另一个服务器已经使用了该端口。一个解决的办法是等待一段时间后重试。
server.on('error', function (e) {
if (e.code == 'EADDRINUSE') {
console.log('Address in use, retrying...');
setTimeout(function () {
server.close();
server.listen(PORT, HOST);
}, 1000);
}
});
(注意,io.js
中所有的socket
都已经设置了SO_REUSEADDR
)
启动一个本地socket
服务器,监听指定路径(path
)上的连接。
这个函数式异步的。当服务器监听了指定路径后,listening
事件将会被触发。最后一个参数callback
将会被添加为listening
事件的监听器。
在UNIX中,local domain
经常被称作UNIX domain
。path
是一个文件系统路径名。它在被创建时会受相同文件名约定(same naming conventions)的限制并且进行权限检查(permissions checks)。它在文件系统中可见,并且在被删除前持续存在。
在Windows中,local doamin
使用一个命名管道(named pipe)实现。path
必须指向\\?\pipe\
或\\.\pipe\.
中的一个条目,但是后者可能会做一些命名管道的处理,如处理..
序列。除去表现,命名管道空间是平坦的(flat)。管道不会持续存在,它们将在最后一个它们的引用关闭后被删除。不要忘记,由于JavaScript
的字符串转义,你必须在指定path
时使用双反斜杠:
net.createServer().listen(
path.join('\\\\?\\pipe', process.cwd(), 'myctl'))
handle
对象可以被设置为一个服务器或一个socket
(或者任意以下划线开头的成员_handle
),或者一个{fd: <n>}
对象。
这将使得服务器使用指定句柄接受连接,但它假设文件描述符或句柄已经被绑定至指定的端口或域名socket
。
在Windows下不支持监听一个文件描述符。
这个函数式异步的。当服务器已被绑定后,listening
事件将会被触发。最后一个参数callback
将会被添加为listening
事件的监听器。
options Object
exclusive Boolean 可选
callback Function 可选
port
,host
和backlog
属性,以及可选的callback
函数,与server.listen(port, [host], [backlog], [callback])
中表现一致。path
可以被指定为一个UNIX socket
。
如果exclusive
是false
(默认),那么工作集群(cluster workers)将会使用相同的底层句柄,处理的连接的职责将会被它们共享。如果exclusive
是true
,那么句柄是不被共享的,企图共享将得到一个报错的结果。下面是一个监听独有端口的例子:
server.listen({
host: 'localhost',
port: 80,
exclusive: true
});
使服务器停止接收新的连接并且保持已存在的连接。这个函数式异步的,当所有的连接都结束时服务器会最终关闭,并处罚一个close
事件。可选的,你可以传递一个回调函数来监听close
事件。如果传递了,那么它的唯一的第一个参数将表示任何可能潜在发生的错误。
返回服务器绑定的地址,协议族名和端口通过操作系统报告。对查找操作系统分配的地址哪个端口被分配非常有用。返回一个有三个属性的对象。如{ port: 12346, family: 'IPv4', address: '127.0.0.1' }
。
例子:
var server = net.createServer(function (socket) {
socket.end("goodbye\n");
});
// grab a random port.
server.listen(function() {
address = server.address();
console.log("opened server on %j", address);
});
在listening
事件触发前,不要调用server.address()
方法。
调用一个server
对象的unref
方法将允许如果它是事件系统中唯一活跃的服务器,程序将会退出。如果服务器已经被调用过这个方法,那么再次调用这个方法将不会有任何效果。
返回server
对象。
与unref
相反,在一个已经被调用unref
方法的server
中调用ref
方法,那么如果它是唯一活跃的服务器时,程序将不会退出(默认)。如果服务器已经被调用过这个方法,那么再次调用这个方法将不会有任何效果。
返回server
对象。
设置了这个属性后,服务器的连接数达到时将会开始拒绝连接。
一旦socket
被使用child_process.fork()
传递给了子进程,这个属性就不被推荐去设置。
这个函数已经被弃用。请使用server.getConnections()
替代。
服务器的当前连接数。
当使用child_process.fork()
传递一个socket
给子进程时,这个属性将变成null
。想要得到正确的结果请使用server.getConnections
。
异步地去获取服务器的当前连接数,在socket
被传递给子进程时仍然可用。
回调函数的两个参数是err
和count
。
net.Server
是一个具有以下事件的EventEmitter
:当调用server.listen
后,服务器已被绑定时触发。
当新的连接产生时触发。socket
是一个net.Socket
实例。
当服务器关闭时触发。注意如果服务器中仍有连接存在,那么这个事件会直到所有的连接都关闭后才触发。
当发生错误时触发。close
事件将会在它之后立即触发。参阅server.listen
。
这个对象是一个TCP或本地socket
的抽象。net.Socket
实例实现了双工流(duplex Stream)接口。它可以被使用者创建,并且被作为客户端(配合connect()
)使用。或者也可以被io.js
创建,并且通过服务器的connection
事件传递给使用者。
创建一个新的socket
对象。
options
是一个有以下默认值的对象:
{ fd: null
allowHalfOpen: false,
readable: false,
writable: false
}
fd
允许你使用一个指定的已存在的socket
文件描述符。设置readable
和/或 writable
为true
将允许从这个socket
中读 和/或 写(注意,仅在传递了passed
时可用)。关于allowHalfOpen
,参阅createServer()
和end
事件。
从给定的socket
打开一个连接。
对于TCPsocket
,options
参数需是一个包含以下属性的对象:
port: 客户端需要连接的端口(必选)。
host: 客户端需要连接的主机(默认:'localhost')
localAddress: 将要绑定的本地接口,为了网络连接。
localPort: 将要绑定的本地端口,为了网络连接。
family : IP协议族版本,默认为4
。
lookup : 自定义查找函数。默认为dns.lookup
。
对于本地domain socket
,options
参数需是一个包含以下属性的对象:
通常这个方法是不需要的,因为通过net.createConnection
打开socket
。只有在你自定义了socket
时才使用它。
这个函数式异步的,当connect
事件触发时,这个socket
就被建立了。如果在连接的过程有问题,那么connect
事件将不会触发,error
将会带着这个异常触发。
connectListener
参数会被自动添加为connect
事件的监听器。
参阅socket.connect(options[, connectListener])
。
net.Socket
的属性,用于socket.write()
。它可以帮助用户获取更快的运行速度。计算机不能一直保持大量数据被写入socket
的状态,网络连接可以很慢。io.js
在内部会排队等候数据被写入socekt
并确保传输连接上的数据完好。 (内部实现为:轮询socekt
的文件描述符等待它为可写)。
内部缓存的可能结果是内存使用会增长。这个属性展示了缓存中还有多少待写入的字符(字符的数目约等于要被写入的字节数,但是缓冲区可能包含字符串,而字符串是惰性编码的,所以确切的字节数是未知的)。
遇到数值很大或增长很快的bufferSize
时,应当尝试使用pause()
和resume()
来控制。
设置socket
的编码作为一个可读流。详情参阅stream.setEncoding()
。
在套接字上发送数据。第二个参数指定了字符串的编码,默认为UTF8。
如果所有数据成功被刷新至了内核缓冲区,则返回true
。如果所有或部分数据仍然在用户内存中排队,则返回false
。drain
事件将会被触发当buffer
再次为空时。
当数据最终被写入时,callback
回调函数将会被执行,但可能不会马上执行。
半关闭一个socket
。比如,它发送一个FIN
报文。可能服务器仍然在发送一些数据。
如果data
参数被指定,那么等同于先调用socket.write(data, encoding)
,再调用socket.end()
。
确保这个socket
上没有I/O活动发生。只在发生错误情况才需要(如处理错误)。
暂停数据读取。data
事件将不会再触发。对于控制上传非常有用。
用于在调用pause()
后,恢复数据读取。
如果socket
在timeout
毫秒中没有活动后,设置其为超时。默认情况下,net.Socket
没有超时。
当超时发生,socket
会收到一个timeout
事件,但是连接将不会被断开。用户必须手动地调用end()
或destroy()
方法。
如果timeout
是0
,那么现有的超时将会被禁用。
可选的callback
参数就会被自动添加为timeout
事件的监听器。
返回一个socket
。
警用纳格算法(Nagle algorithm)。默认情况下TCP连接使用纳格算法,它们的数据在被发送前会被缓存。设置noDelay
为true
将会在每次socket.write()
时立刻发送数据。noDelay
默认为true
。
返回一个socket
。
启用/警用长连接功能,并且在第一个在闲置socket
的长连接probe
被发送前,可选得设置初始延时。enable
默认为false
。
设定initialDelay
(毫秒),来设定在收到的最后一个数据包和第一个长连接probe
之间的延时。将initialDelay
设成0
会让值保持不变(默认值或之前所设的值)。默认为0
。
返回一个socket
。
返回绑定的地址,协议族名和端口通过操作系统报告。对查找操作系统分配的地址哪个端口被分配非常有用。返回一个有三个属性的对象。如{ port: 12346, family: 'IPv4', address: '127.0.0.1' }
。
调用一个socket
对象的unref
方法将允许如果它是事件系统中唯一活跃的socket
,程序将会退出。如果socket
已经被调用过这个方法,那么再次调用这个方法将不会有任何效果。
返回socket
对象。
与unref
相反,在一个已经被调用unref
方法的socket
中调用ref
方法,那么如果它是唯一活跃的socket
时,程序将不会退出(默认)。如果socket
已经被调用过这个方法,那么再次调用这个方法将不会有任何效果。
返回socket
对象。
远程IP地址字符串。例如,'74.125.127.100'
或'2001:4860:a005::68'
。
远程IP协议族字符串。例如,'IPv4'
或'IPv6'
。
远程端口数值。例如,80
或21
。
远程客户端正连接的本地IP地址字符串。例如,如果你正在监听'0.0.0.0'
并且客户端连接在'192.168.1.1'
,其值将为'192.168.1.1'
。
本地端口数值。例如,80
或21
。
接受的字节数。
发送的字节数。
net.Socket
实例是一个包含以下事件的EventEmitter
:在解析主机名后,连接主机前触发。对UNIX socket
不适用。
dns.lookup()
在socket
连接成功建立后触发。参阅connect()
。
在接受到数据后触发。参数将会是一个Buffer
或一个字符串。数据的编码由socket.setEncoding()
设置(更多详细信息请查看可读流章节)。
注意,当socket
触发data
事件时,如果没有监听器存在。那么数据将会丢失。
当另一端的socket
发送一个FIN
报文时触发。
默认情况(allowHalfOpen == false
)下,一旦一个socket
的文件描述符被从它的等待写队列(pending write queue)中写出,socket
会销毁它。但是,当设定allowHalfOpen == true
后,socket
不会在它这边自动调用end()
,允许用户写入任意数量的数据,需要注意的是用户需要在自己这边调用end()
。
当socket
因不活动而超时时触发。这只是来表示socket
被限制。用户必须手动关闭连接。
参阅socket.setTimeout()
。
当写缓冲为空时触发。可以被用来控制上传流量。
参阅socket.write()
的返回值。
当发生错误时触发。close
事件会紧跟着这个事件触发。
socket
有一个传输错误时为true
当socket
完全关闭时触发。参数had_error
是一个表示socket
是否是因为传输错误而关闭的布尔值。
测试input
是否是一个IP地址。如果是不合法字符串时,会返回0
。如果是IPv4地址则返回4
,是IPv6地址则返回6
。
如果input
是一个IPv4地址则返回true
,否则返回false
。
如果input
是一个IPv6地址则返回true
,否则返回false
。