99热99这里只有精品6国产,亚洲中文字幕在线天天更新,在线观看亚洲精品国产福利片 ,久久久久综合网
Swift
編程
Swift51.com
首頁
社區(qū)
▼
資訊
問答
分享
建議
開源代碼
Xcode下載
Swift教程
hot
登錄
注冊
當(dāng)前位置:
首頁
> 分享
歡迎加入QQ討論群258996829
蘋果6袋
6
麥子學(xué)院
Nodejs中net模塊如何使用?
發(fā)布時間:2016-11-21 16:25 回復(fù):0 查看:2509 最后回復(fù):2016-11-21 16:25
net模塊是同樣是nodejs的核心模塊。在http模塊概覽里提到,http.Server繼承了net.Server,此外,http客戶端與http服務(wù)端的通信均依賴于socket(net.Socket)。也就是說,做node服務(wù)端編程,net基本是繞不開的一個模塊。本文就和大家詳細(xì)扒一扒Nodejs的net相關(guān)用法,希望對大家
學(xué)習(xí)Nodejs
有所幫助吧。
從組成來看,net模塊主要包含兩部分,了解socket編程的同學(xué)應(yīng)該比較熟悉了:
· net.Server:TCP server,內(nèi)部通過socket來實現(xiàn)與客戶端的通信。
· net.Socket:tcp/本地 socket的node版實現(xiàn),它實現(xiàn)了全雙工的stream接口。
本文從一個簡單的 tcp服務(wù)端/客戶端 的例子開始講解,好讓讀者有個概要的認(rèn)識。接著再分別介紹 net.Server、net.Socket 比較重要的API、屬性、事件。
對于初學(xué)者,建議把文中的例子本地跑一遍加深理解。
簡單的 server+client 例子
tcp服務(wù)端程序如下:
var net = require('net');
var PORT = 3000;var HOST = '127.0.0.1';
// tcp服務(wù)端var server = net.createServer(function(socket){
console.log('服務(wù)端:收到來自客戶端的請求');
socket.on('data', function(data){
console.log('服務(wù)端:收到客戶端數(shù)據(jù),內(nèi)容為{'+ data +'}');
// 給客戶端返回數(shù)據(jù)
socket.write('你好,我是服務(wù)端');
});
socket.on('close', function(){
console.log('服務(wù)端:客戶端連接斷開');
});
});
server.listen(PORT, HOST, function(){
console.log('服務(wù)端:開始監(jiān)聽來自客戶端的請求');
});
tcp客戶端如下:
var net = require('net');
var PORT = 3000;var HOST = '127.0.0.1';
// tcp客戶端var client = net.createConnection(PORT, HOST);
client.on('connect', function(){
console.log('客戶端:已經(jīng)與服務(wù)端建立連接');
});
client.on('data', function(data){
console.log('客戶端:收到服務(wù)端數(shù)據(jù),內(nèi)容為{'+ data +'}');
});
client.on('close', function(data){
console.log('客戶端:連接斷開');
});
client.end('你好,我是客戶端');
運行服務(wù)端、客戶端代碼,控制臺分別輸出如下:
服務(wù)端:
服務(wù)端:開始監(jiān)聽來自客戶端的請求
服務(wù)端:收到來自客戶端的請求
服務(wù)端:收到客戶端數(shù)據(jù),內(nèi)容為{你好,我是客戶端}
服務(wù)端:客戶端連接斷開
客戶端:
客戶端:已經(jīng)與服務(wù)端建立連接
客戶端:收到服務(wù)端數(shù)據(jù),內(nèi)容為{你好,我是服務(wù)端}
客戶端:連接斷開
服務(wù)端 net.Server
server.address()
返回服務(wù)端的地址信息,比如綁定的ip地址、端口等。
console.log( server.address() );
// 輸出如下 { port: 3000, family: 'IPv4', address: '127.0.0.1' }
server.close(callback])
關(guān)閉服務(wù)器,停止接收新的客戶端請求。有幾點注意事項:
· 對正在處理中的客戶端請求,服務(wù)器會等待它們處理完(或超時),然后再正式關(guān)閉。
· 正常關(guān)閉的同時,callback 會被執(zhí)行,同時會觸發(fā) close 事件。
· 異常關(guān)閉的同時,callback 也會執(zhí)行,同時將對應(yīng)的 error 作為參數(shù)傳入。(比如還沒調(diào)用 server.listen(port) 之前,就調(diào)用了server.close())
下面會通過兩個具體的例子進(jìn)行對比,先把結(jié)論列出來
· 已調(diào)用server.listen():正常關(guān)閉,close事件觸發(fā),然后callback執(zhí)行,error參數(shù)為undefined
· 未調(diào)用server.listen():異常關(guān)閉,close事件觸發(fā),然后callback執(zhí)行,error為具體的錯誤信息。(注意,error 事件沒有觸發(fā))
例子1:服務(wù)端正常關(guān)閉
var net = require('net');var PORT = 3000;var HOST = '127.0.0.1';var noop = function(){};
// tcp服務(wù)端var server = net.createServer(noop);
server.listen(PORT, HOST, function(){
server.close(function(error){
if(error){
console.log( 'close回調(diào):服務(wù)端異常:' + error.message );
}else{
console.log( 'close回調(diào):服務(wù)端正常關(guān)閉' );
}
});
});
server.on('close', function(){
console.log( 'close事件:服務(wù)端關(guān)閉' );
});
server.on('error', function(error){
console.log( 'error事件:服務(wù)端異常:' + error.message );
});
輸出為:
close事件:服務(wù)端關(guān)閉close回調(diào):服務(wù)端正常關(guān)閉
例子2:服務(wù)端異常關(guān)閉
代碼如下
var net = require('net');var PORT = 3000;var HOST = '127.0.0.1';var noop = function(){};
// tcp服務(wù)端var server = net.createServer(noop);
// 沒有正式啟動請求監(jiān)聽// server.listen(PORT, HOST);
server.on('close', function(){
console.log( 'close事件:服務(wù)端關(guān)閉' );
});
server.on('error', function(error){
console.log( 'error事件:服務(wù)端異常:' + error.message );
});
server.close(function(error){
if(error){
console.log( 'close回調(diào):服務(wù)端異常:' + error.message );
}else{
console.log( 'close回調(diào):服務(wù)端正常關(guān)閉' );
}
});
輸出為:
close事件:服務(wù)端關(guān)閉close回調(diào):服務(wù)端異常:Not running
server.ref()/server.unref()
了解node事件循環(huán)的同學(xué)對這兩個API應(yīng)該不陌生,主要用于將server 加入事件循環(huán)/從事件循環(huán)里面剔除,影響就在于會不會影響進(jìn)程的退出。
對出學(xué)習(xí)net的同學(xué)來說,并不需要特別關(guān)注,感興趣的自己做下實驗就好。
事件 listening/connection/close/error
· listening:調(diào)用 server.listen(),正式開始監(jiān)聽請求的時候觸發(fā)。
· connection:當(dāng)有新的請求進(jìn)來時觸發(fā),參數(shù)為請求相關(guān)的 socket。
· close:服務(wù)端關(guān)閉的時候觸發(fā)。
· error:服務(wù)出錯的時候觸發(fā),比如監(jiān)聽了已經(jīng)被占用的端口。
幾個事件都比較簡單,這里僅舉個 connection 的例子。
從測試結(jié)果可以看出,有新的客戶端連接產(chǎn)生時,net.createServer(callback) 中的callback回調(diào) 會被調(diào)用,同時 connection 事件注冊的回調(diào)函數(shù)也會被調(diào)用。
事實上,net.createServer(callback) 中的 callback 在node內(nèi)部實現(xiàn)中 也是加入了做為 connection事件 的監(jiān)聽函數(shù)。感興趣的可以看下node的源碼。
var net = require('net');var PORT = 3000;var HOST = '127.0.0.1';var noop = function(){};
// tcp服務(wù)端var server = net.createServer(function(socket){
socket.write('1. connection 觸發(fā)\n');
});
server.on('connection', function(socket){
socket.end('2. connection 觸發(fā)\n');
});
server.listen(PORT, HOST);
通過下面命令測試下效果
curl http://127.0.0.1:3000
輸出:
1. connection 觸發(fā)2. connection 觸發(fā)
客戶端 net.Socket
在文章開頭已經(jīng)舉過客戶端的例子,這里再把例子貼一下。(備注:嚴(yán)格來說不應(yīng)該把 net.Socket 叫做客戶端,這里方便講解而已)
單從node官方文檔來看的話,感覺 net.Socket 比 net.Server 要復(fù)雜很多,有更多的API、事件、屬性。但實際上,把 net.Socket 相關(guān)的API、事件、屬性 進(jìn)行歸類下,會發(fā)現(xiàn),其實也不是特別復(fù)雜。
具體請看下一小節(jié)內(nèi)容。
var net = require('net');
var PORT = 3000;var HOST = '127.0.0.1';
// tcp客戶端var client = net.createConnection(PORT, HOST);
client.on('connect', function(){
console.log('客戶端:已經(jīng)與服務(wù)端建立連接');
});
client.on('data', function(data){
console.log('客戶端:收到服務(wù)端數(shù)據(jù),內(nèi)容為{'+ data +'}');
});
client.on('close', function(data){
console.log('客戶端:連接斷開');
});
client.end('你好,我是客戶端');
API、屬性歸類
以下對net.Socket的API跟屬性,按照用途進(jìn)行了大致的分類,方便讀者更好的理解。大部分API跟屬性都比較簡單,看下文檔就知道做什么的,這里就先不展開。
連接相關(guān)
· socket.connect():有3種不同的參數(shù),用于不同的場景;
· socket.setTimeout():用來進(jìn)行連接超時設(shè)置。
· socket.setKeepAlive():用來設(shè)置長連接。
· socket.destroy()、socket.destroyed:當(dāng)錯誤發(fā)生時,用來銷毀socket,確保這個socket上不會再有其他的IO操作。
數(shù)據(jù)讀、寫相關(guān)
socket.write()、socket.end()、socket.pause()、socket.resume()、socket.setEncoding()、socket.setNoDelay()
數(shù)據(jù)屬性相關(guān)
socket.bufferSize、socket.bytesRead、socket.bytesWritten
事件循環(huán)相關(guān)
socket.ref()、socket.unref()
地址相關(guān)
· socket.address()
· socket.remoteAddress、socket.remoteFamily、socket.remotePort
· socket.localAddress/socket.localPort
事件簡介
· data:當(dāng)收到另一側(cè)傳來的數(shù)據(jù)時觸發(fā)。
· connect:當(dāng)連接建立時觸發(fā)。
· close:連接斷開時觸發(fā)。如果是因為傳輸錯誤導(dǎo)致的連接斷開,則參數(shù)為error。
· end:當(dāng)連接另一側(cè)發(fā)送了 FIN 包的時候觸發(fā)(讀者可以回顧下HTTP如何斷開連接的)。默認(rèn)情況下(allowHalfOpen == false),socket會完成自我銷毀操作。但你也可以把 allowHalfOpen 設(shè)置為 true,這樣就可以繼續(xù)往socket里寫數(shù)據(jù)。當(dāng)然,最后你需要手動調(diào)用 socket.end()
· error:當(dāng)有錯誤發(fā)生時,就會觸發(fā),參數(shù)為error。(官方文檔基本一句話帶過,不過考慮到出錯的可能太多,也可以理解)
· timeout:提示用戶,socket 已經(jīng)超時,需要手動關(guān)閉連接。
· drain:當(dāng)寫緩存空了的時候觸發(fā)。(不是很好描述,具體可以看下stream的介紹)
· lookup:域名解析完成時觸發(fā)。
文章來源:chyingp
取消引用
您還未登錄,
請先登錄
提 問
熱門帖子
iDev 全平臺開發(fā)者大會門票免費送!限量10張!
蘋果Mac Pro垃圾桶 最低配的ME253CH
本人想買個蘋果電腦搞開發(fā),哪位大俠指點下
求助:failable initializer 'init(name:)' cannot override a non-failable initializer
為慶祝Swift發(fā)布1個月,雨燕社區(qū)正式上線。
在UITextFeild里輸入數(shù)據(jù),這個數(shù)據(jù)怎么做加減乘除?
Swift 高仿喜馬拉雅FM
要成為自由職業(yè)者?先要學(xué)會蘋果的Swift哦
用swift實現(xiàn)的調(diào)用系統(tǒng)相機(jī),相冊的DEMO
關(guān)于嵌入式引用\()
Swift 教程
最新帖子
swift_5.3可以更新了
swift如何實現(xiàn)左滑刪除
IBM Swift Sandbox訪問
Thread 18: Fatal error: 'try!' expression unexpectedly raised an error: Error
跟隨手勢滑動的ScrollableTextField
Swift5.0什么時候出
什么時候出5.0
PerfectTemplate 無法編譯
WWDC19 蘋果宣布全新 UI 框架 SwiftUI
水平滾動視圖Carousel
Xcode 9.4下載
?
Copyright © 2017 Swift 編程 版權(quán)所有
推動 Swift 成為最受歡迎的編程語言!
友鏈、商務(wù)合作:service??swift51.com
手機(jī)版