穩(wěn)定性: 3 - 穩(wěn)定
net
模塊提供了異步網(wǎng)絡(luò)封裝,該Node.js模塊包含了創(chuàng)建服務(wù)器/客戶端的方法(調(diào)用 streams),你可以通過(guò)調(diào)用 require('net')
包含這個(gè)模塊,訪問方法如下所示:
const net = require('net');
創(chuàng)建一個(gè)TCP服務(wù)器。參數(shù)connectionListener
自動(dòng)給'connection'事件創(chuàng)建監(jiān)聽器。
options
包含有以下默認(rèn)值:
{
allowHalfOpen: false,
pauseOnConnect: false
}
如果allowHalfOpen
=true
,當(dāng)另一端socket發(fā)送FIN包時(shí),socket不會(huì)自動(dòng)發(fā)送FIN包。socket變?yōu)椴豢勺x,但仍可寫。你需要顯式的調(diào)用end()
方法。更多信息參見'end'事件。
如果pauseOnConnect
=true
,當(dāng)連接到來(lái)的時(shí)候相關(guān)聯(lián)的socket將會(huì)暫停。它允許在初始進(jìn)程不讀取數(shù)據(jù)情況下,讓連接在進(jìn)程間傳遞。調(diào)用resume()
從暫停的socket里讀取數(shù)據(jù)。
下面是一個(gè)監(jiān)聽8124端口連接的應(yīng)答服務(wù)器的例子:
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
來(lái)測(cè)試:
telnet localhost 8124
要監(jiān)聽socket t/tmp/echo.sock
,僅需要改倒數(shù)第三行代碼,如下所示:
server.listen('/tmp/echo.sock', function() { //'listening' listener
使用nc
連接到一個(gè)UNIX domain socket服務(wù)器:
nc -U /tmp/echo.sock
工廠方法,返回一個(gè)新的'net.Socket',并連接到指定的地址和端口。
當(dāng)socket建立的時(shí)候,將會(huì)觸發(fā)'connect'事件。
和'net.Socket'有相同的方法。
對(duì)于TCP sockets,參數(shù)options
因?yàn)橄铝袇?shù)的對(duì)象:
port
: 客戶端連接到Port的端口(必須)。
host
: 客戶端要連接到得主機(jī)。默認(rèn)'localhost'
.
localAddress
: 網(wǎng)絡(luò)連接綁定的本地接口。
localPort
: 網(wǎng)絡(luò)連接綁定的本地端口。
family
: IP棧版本。默認(rèn)4
。對(duì)于本地域socket,參數(shù)options
因?yàn)橄铝袇?shù)的對(duì)象:
path
: 客戶端連接到得路徑(必須).通用選項(xiàng):
如果allowHalfOpen
=true
, 當(dāng)另一端socket發(fā)送FIN包時(shí)socket不會(huì)自動(dòng)發(fā)送FIN包。socket變?yōu)椴豢勺x,但仍可寫。你需要顯式的調(diào)用end()
方法。更多信息參見'end'事件。
connectListener
參數(shù)將會(huì)作為監(jiān)聽器添加到'connect'事件上。
下面是一個(gè)用上述方法應(yīng)答服務(wù)器的客戶端例子:
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
,僅需將第二行代碼改為如下的內(nèi)容:
var client = net.connect({path: '/tmp/echo.sock'});
創(chuàng)建一個(gè)到端口port
和主機(jī)host
的TCP連接。如果忽略主機(jī)host
,則假定為'localhost'
。參數(shù)connectListener
將會(huì)作為監(jiān)聽器添加到'connect'事件。
這是工廠方法,返回一個(gè)新的'net.Socket'。
創(chuàng)建到path
的unix socket連接。參數(shù)connectListener
將會(huì)作為監(jiān)聽器添加到'connect'事件上。
這是工廠方法,返回一個(gè)新的'net.Socket'。
這個(gè)類用來(lái)創(chuàng)建一個(gè)TCP或本地服務(wù)器。
開始接受指定端口port
和主機(jī)host
的連接。如果忽略主機(jī)host
, 服務(wù)器將會(huì)接受任何IPv4地址(INADDR_ANY
)的直接連接。端口為0,則會(huì)分配一個(gè)隨機(jī)端口。
積壓量(Backlog)為連接等待隊(duì)列的最大長(zhǎng)度。實(shí)際長(zhǎng)度由您的操作系統(tǒng)通過(guò) sysctl 設(shè)定,比如 linux 上的tcp_max_syn_backlog
和 somaxconn
。這個(gè)參數(shù)默認(rèn)值是511(不是512)。
這是異步函數(shù)。當(dāng)服務(wù)器被綁定時(shí)會(huì)觸發(fā)'listening'事件。最后一個(gè)參數(shù)callback
將會(huì)作為'listening'事件的監(jiān)聽器。
有些用戶會(huì)遇到EADDRINUSE
錯(cuò)誤,它表示另外一個(gè)服務(wù)器已經(jīng)運(yùn)行在所請(qǐng)求的端口上。處理這個(gè)情況的辦法是等一段事件再重試:
server.on('error', function (e) {
if (e.code == 'EADDRINUSE') {
console.log('Address in use, retrying...');
setTimeout(function () {
server.close();
server.listen(PORT, HOST);
}, 1000);
}
});
(注意:Node中的所有socket已設(shè)置了SO_REUSEADDR
)
path
{String}callback
{Function}啟動(dòng)一個(gè)本地socket服務(wù)器,監(jiān)聽指定path
的連接。
這是異步函數(shù)。綁定服務(wù)器后,會(huì)觸發(fā)'listening'事件。最后一個(gè)參數(shù)callback
將會(huì)作為'listening'事件的監(jiān)聽器。
UNIX上,本地域通常默認(rèn)為UNIX域。參數(shù)path
是文件系統(tǒng)路徑,就和創(chuàng)建文件時(shí)一樣,它也遵從命名規(guī)則和權(quán)限檢查,并且在文件系統(tǒng)里可見,并持續(xù)到關(guān)閉關(guān)聯(lián)。
Windows上,本地域通過(guò)命名管道實(shí)現(xiàn)。路徑必須是以\\?\pipe\
或\\.\pipe\
入口。任意字符串都可以,不過(guò)之后進(jìn)行相同的管道命名處理,比如解決..
序列。管道命名空間是平的。管道不會(huì)一直持久,當(dāng)最后一個(gè)引用關(guān)閉的時(shí)候,管道將會(huì)移除。不要忘記javascript字符字符串轉(zhuǎn)義要求路徑使用雙反斜杠,比如:
net.createServer().listen(
path.join('\\\\?\\pipe', process.cwd(), 'myctl'))
handle
{Object}callback
{Function}
handle
對(duì)象可以設(shè)置成server或socket(任意以下劃線_handle
開頭的類),或者是{fd: <n>}
對(duì)象。
這將是服務(wù)器用指定的句柄接收連接,前提是文件描述符或句柄已經(jīng)綁定到端口或域socket。
Windows不支持監(jiān)聽文件句柄。
這是異步函數(shù)。當(dāng)服務(wù)器已經(jīng)被綁定,將會(huì)觸發(fā)'listening'事件。最后一個(gè)參數(shù)callback
將會(huì)作為'listening'事件的監(jiān)聽器。
options
{Object} - 必須有。支持以下屬性:port
{Number} - 可選。host
{String} - 可選。backlog
{Number} - 可選。path
{String} - 可選。exclusive
{Boolean} - 可選。callback
{Function} - 可選。options
的屬性:端口port
,主機(jī)host
,和backlog
,以及可選參數(shù)callback函數(shù),他們?cè)谝黄鹫{(diào)用server.listen(port, [host], [backlog], [callback])。還有,參數(shù)path
可以用來(lái)指定UNIX socket。
如果參數(shù)exclusive
是false
(默認(rèn)值),集群進(jìn)程將會(huì)使用同一個(gè)句柄,允許連接共享。當(dāng)參數(shù)exclusive
是true
時(shí),句柄不會(huì)共享,如果共享端口會(huì)返回錯(cuò)誤。監(jiān)聽獨(dú)家端口例子如下:
server.listen({
host: 'localhost',
port: 80,
exclusive: true
});
服務(wù)器停止接收新的連接,保持現(xiàn)有連接。這是異步函數(shù),當(dāng)所有連接結(jié)束的時(shí)候服務(wù)器會(huì)關(guān)閉,并會(huì)觸發(fā)'close'
事件。你可以傳一個(gè)回調(diào)函數(shù)來(lái)監(jiān)聽'close'
事件。如果存在,將會(huì)調(diào)用回調(diào)函數(shù),錯(cuò)誤(如果有)作為唯一參數(shù)。
操作系統(tǒng)返回綁定的地址,協(xié)議族名和服務(wù)器端口。查找哪個(gè)端口已經(jīng)被系統(tǒng)綁定時(shí),非常有用。返回的對(duì)象有3個(gè)屬性,比如:{ 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'
事件觸發(fā)前,不要調(diào)用server.address()
。
如果這是事件系統(tǒng)中唯一一個(gè)活動(dòng)的服務(wù)器,調(diào)用unref
將允許程序退出。如果服務(wù)器已被unref,則再次調(diào)用unref并不會(huì)產(chǎn)生影響。
與unref
相反,如果這是唯一的服務(wù)器,在之前被unref
了的服務(wù)器上調(diào)用ref
將不會(huì)讓程序退出(默認(rèn)行為)。如果服務(wù)器已經(jīng)被ref
,則再次調(diào)用ref
并不會(huì)產(chǎn)生影響。
設(shè)置這個(gè)選項(xiàng)后,當(dāng)服務(wù)器連接數(shù)超過(guò)數(shù)量時(shí)拒絕新連接。
一旦已經(jīng)用child_process.fork()
方法將socket發(fā)送給子進(jìn)程, 就不推薦使用這個(gè)選項(xiàng)。
已經(jīng)拋棄這個(gè)函數(shù)。請(qǐng)用server.getConnections()代替。服務(wù)器上當(dāng)前連接的數(shù)量。
當(dāng)調(diào)用child_process.fork()
發(fā)送一個(gè)socket給子進(jìn)程時(shí),它將變?yōu)?code>null。 要輪詢子進(jìn)程來(lái)獲取當(dāng)前活動(dòng)連接的數(shù)量,請(qǐng)用server.getConnections
代替。
異步獲取服務(wù)器當(dāng)前活躍連接的數(shù)量。當(dāng)socket發(fā)送給子進(jìn)程后才有效;
回調(diào)函數(shù)有2個(gè)參數(shù)err
和count
。
net.Server
是事件分發(fā)器EventEmitter, 有以下事件:
當(dāng)服務(wù)器調(diào)用server.listen
綁定后會(huì)觸發(fā)。
當(dāng)新連接創(chuàng)建后會(huì)被觸發(fā)。socket
是net.Socket
實(shí)例。
服務(wù)器關(guān)閉時(shí)會(huì)觸發(fā)。注意,如果存在連接,這個(gè)事件不會(huì)被觸發(fā)直到所有的連接關(guān)閉。
發(fā)生錯(cuò)誤時(shí)觸發(fā)。'close'事件將被下列事件直接調(diào)用。請(qǐng)查看server.listen
例子。
這個(gè)對(duì)象是TCP或UNIX Socket的抽象。net.Socket
實(shí)例實(shí)現(xiàn)了一個(gè)雙工流接口。他們可以在用戶創(chuàng)建客戶端(使用connect())時(shí)使用,或者由Node創(chuàng)建它們,并通過(guò)connection
服務(wù)器事件傳遞給用戶。
構(gòu)造一個(gè)新的socket對(duì)象。
options
對(duì)象有以下默認(rèn)值:
{ fd: null
allowHalfOpen: false,
readable: false,
writable: false
}
參數(shù)fd
允許你指定一個(gè)存在的文件描述符。將readable
和(或)writable
設(shè)為true
,允許在這個(gè)socket上讀和(或)寫(注意,僅在參數(shù)fd
有效時(shí))。關(guān)于allowHalfOpen
,參見createServer()
和'end'
事件。
使用傳入的socket打開一個(gè)連接。如果指定了端口port
和主機(jī)host
,TCP socket將打開socket。如果忽略參數(shù)host
,則默認(rèn)為localhost
。如果指定了 path
,socket將會(huì)被指定路徑的unix socket打開。
通常情況不需要使用這個(gè)函數(shù),比如使用net.createConnection
打開socket。只有你實(shí)現(xiàn)了自己的socket時(shí)才會(huì)用到。
這是異步函數(shù)。當(dāng)'connect'事件被觸發(fā)時(shí),socket已經(jīng)建立。如果這是問題連接,'connect'
事件不會(huì)被觸發(fā),將會(huì)拋出'error'
事件。
參數(shù)connectListener
將會(huì)作為監(jiān)聽器添加到'connect'事件。
socket.bufferSize是net.Socket
的一個(gè)屬性,用于socket.write()
。它能夠幫助用戶獲取更快的運(yùn)行速度。計(jì)算機(jī)不能一直處于寫入大量數(shù)據(jù)狀態(tài)--網(wǎng)絡(luò)連接可能太慢。Node在內(nèi)部會(huì)將排隊(duì)數(shù)據(jù)寫入到socket,并在網(wǎng)絡(luò)可用時(shí)發(fā)送。(內(nèi)部實(shí)現(xiàn):輪詢socket的文件描述符直到變?yōu)榭蓪懀?/p>
這種內(nèi)部緩沖的缺點(diǎn)是會(huì)增加內(nèi)存使用量。這個(gè)屬性表示當(dāng)前準(zhǔn)備寫的緩沖字符數(shù)。(字符的數(shù)量等于準(zhǔn)備寫入的字節(jié)的數(shù)量,但是緩沖區(qū)可能包含字符串,這些字符串是惰性編碼的,所以準(zhǔn)確的字節(jié)數(shù)還無(wú)法知道)。
遇到很大增長(zhǎng)很快的bufferSize
時(shí),用戶可用嘗試用pause()
和resume()
來(lái)控制字符流。
設(shè)置socket的編碼為可讀流。更多信息參見stream.setEncoding()
在socket上發(fā)送數(shù)據(jù)。第二個(gè)參數(shù)指定了字符串的編碼,默認(rèn)是UTF8編碼。
如果所有數(shù)據(jù)成功刷新到內(nèi)核緩沖區(qū),返回true
。如果數(shù)據(jù)全部或部分在用戶內(nèi)存里,返回false
。當(dāng)緩沖區(qū)為空的時(shí)候會(huì)觸發(fā)'drain'
。
當(dāng)數(shù)據(jù)最終被完整寫入的的時(shí)候,可選的callback
參數(shù)會(huì)被執(zhí)行,但不一定會(huì)馬上執(zhí)行。
半關(guān)閉socket。例如,它發(fā)送一個(gè)FIN包??赡芊?wù)器仍在發(fā)送數(shù)據(jù)。
如果參數(shù)data
不為空,等同于調(diào)用socket.write(data, encoding)
后再調(diào)用socket.end()
。
確保沒有I/O活動(dòng)在這個(gè)套接字上。只有在錯(cuò)誤發(fā)生情況下才需要。(處理錯(cuò)誤等等)。
暫停讀取數(shù)據(jù)。就是說(shuō),不會(huì)再觸發(fā)data
事件。對(duì)于控制上傳非常有用。
調(diào)用pause()
后想恢復(fù)讀取數(shù)據(jù)。
socket閑置時(shí)間超過(guò)timeout
毫秒后 ,將socket設(shè)置為超時(shí)。
觸發(fā)空閑超時(shí)事件時(shí),socket將會(huì)收到'timeout'
事件,但是連接不會(huì)被斷開。用戶必須手動(dòng)調(diào)用end()
或destroy()
這個(gè)socket。
如果timeout
= 0,那么現(xiàn)有的閑置超時(shí)會(huì)被禁用
可選的callback參數(shù)將會(huì)被添加成為'timeout'事件的一次性監(jiān)聽器。
禁用納格(Nagle)算法。默認(rèn)情況下TCP連接使用納格算法,在發(fā)送前他們會(huì)緩沖數(shù)據(jù)。將noDelay
設(shè)置為true
將會(huì)在調(diào)用socket.write()
時(shí)立即發(fā)送數(shù)據(jù)。noDelay
默認(rèn)值為true
。
禁用/啟用長(zhǎng)連接功能,并在發(fā)送第一個(gè)在閑置socket上的長(zhǎng)連接 probe 之前,可選地設(shè)定初始延時(shí)。默認(rèn)為false。
設(shè)定initialDelay
(毫秒),來(lái)設(shè)定收到的最后一個(gè)數(shù)據(jù)包和第一個(gè)長(zhǎng)連接probe之間的延時(shí)。將initialDelay設(shè)為0,將會(huì)保留默認(rèn)(或者之前)的值。默認(rèn)值為0。
操作系統(tǒng)返回綁定的地址,協(xié)議族名和服務(wù)器端口。返回的對(duì)象有3個(gè)屬性,比如{ port: 12346, family: 'IPv4', address: '127.0.0.1' }
。
如果這是事件系統(tǒng)中唯一一個(gè)活動(dòng)的服務(wù)器,調(diào)用unref
將允許程序退出。如果服務(wù)器已被unref,則再次調(diào)用unref并不會(huì)產(chǎn)生影響。
與unref
相反,如果這是唯一的服務(wù)器,在之前被unref
了的服務(wù)器上調(diào)用ref
將不會(huì)讓程序退出(默認(rèn)行為)。如果服務(wù)器已經(jīng)被ref
,則再次調(diào)用ref
并不會(huì)產(chǎn)生影響。
遠(yuǎn)程的IP地址字符串,例如:'74.125.127.100'
或者'2001:4860:a005::68'
。
遠(yuǎn)程IP協(xié)議族字符串,比如'IPv4'
或者'IPv6'
。
遠(yuǎn)程端口,數(shù)字表示,例如:80
或者21
。
網(wǎng)絡(luò)連接綁定的本地接口遠(yuǎn)程客戶端正在連接的本地IP地址,字符串表示。例如,如果你在監(jiān)聽'0.0.0.0'而客戶端連接在'192.168.1.1',這個(gè)值就會(huì)是 '192.168.1.1'。
本地端口地址,數(shù)字表示。例如:80
或者21
。
接收到得字節(jié)數(shù)。
發(fā)送的字節(jié)數(shù)。
net.Socket
是事件分發(fā)器EventEmitter的實(shí)例, 有以下事件:
在解析域名后,但在連接前,觸發(fā)這個(gè)事件。對(duì)UNIX sokcet不適用。
err
{Error | Null} 錯(cuò)誤對(duì)象。參見dns.lookup().address
{String} IP地址。family
{String | Null} 地址類型。參見dns.lookup().當(dāng)成功建立socket連接時(shí)觸發(fā)。參見connect()
。
當(dāng)接收到數(shù)據(jù)時(shí)觸發(fā)。參數(shù)data
可以是Buffer
或String
。使用socket.setEncoding()
設(shè)定數(shù)據(jù)編碼。(更多信息參見Readable Stream)。
當(dāng)Socket
觸發(fā)一個(gè)'data'
事件時(shí),如果沒有監(jiān)聽器,數(shù)據(jù)將會(huì)丟失。
當(dāng)socket另一端發(fā)送FIN包時(shí),觸發(fā)該事件。
默認(rèn)情況下(allowHalfOpen == false
),一旦socket將隊(duì)列里的數(shù)據(jù)寫完畢,socket將會(huì)銷毀它的文件描述符。如果allowHalfOpen == true
,socket不會(huì)從它這邊自動(dòng)調(diào)用end(),使的用戶可以隨意寫入數(shù)據(jù),而讓用戶端自己調(diào)用end()。
當(dāng)socket空閑超時(shí)時(shí)觸發(fā),僅是表明socket已經(jīng)空閑。用戶必須手動(dòng)關(guān)閉連接。
參見:socket.setTimeout()
當(dāng)寫緩存為空得時(shí)候觸發(fā)??捎脕?lái)控制上傳。
參見:socket.write()
的返回值。
錯(cuò)誤發(fā)生時(shí)觸發(fā)。以下事件將會(huì)直接觸發(fā)'close'
事件。
had_error
{Boolean} 如果socket傳輸錯(cuò)誤,為true
當(dāng)socket完全關(guān)閉時(shí)觸發(fā)。參數(shù)had_error
是boolean,它表示是否因?yàn)閭鬏斿e(cuò)誤導(dǎo)致socket關(guān)閉。
測(cè)試是否輸入的為IP地址。字符串無(wú)效時(shí)返回0。IPV4情況下返回4,IPV6情況下返回6.
如果輸入的地址為IPV4,返回true,否則返回false。
如果輸入的地址為IPV6,返回true,否則返回false。
更多建議: