• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • nodejs:net模塊學習

    nodejs:net模塊學習

    net模塊是是nodejs的一個核心模塊。而且,http客戶端與http服務端的通信均依賴于socket(net.Socket)。我也來學習一波

    net模塊的組成

    在這里插入圖片描述
    不難看出,net模塊主要包含兩部分:

    • net.Server:TCP server,內部通過socket來實現與客戶端的通信。
    • net.Socket:tcp/本地socket的node版實現,它實現了全雙工的stream接口。

    簡單例子

    netServer.js(服務端):

    //導入net模塊
    const net =require("net");
    
    //創建server
    const server = net.createServer((socket)=>{
    	socket.write("Hello");
    	socket.on("data",(data)=>{
    		//轉換格式,得到的data是buffer類型
    		console.log(data.toString());
    	});
    	socket.on("error",()=>{
    		console.log("socket對象發生error事件");
    	});
    	socket.on("close",()=>{
    		console.log("socket對象發生close事件");
    	})
    })
    
    //捕獲server對象發生錯誤
    server.on("error",()=>{
    	console.log("server對象發生error事件");
    })
    
    //監聽端口
    server.listen(8888,()=>{
    	console.log("socket已成功開啟8888端口");
    })
    

    netClient.js(客戶端):

    const net =require("net");
    
    //創建連接
    let socket = net.createConnection(8888,"192.0.0.10",()=>{
    	console.log("已經成功連接到服務器了,可以通訊了");
    })
    
    socket.on("data",(data)=>{
    	console.log(data.toString());
    	socket.write("兔子哪里跑");
    })
    

    在代碼對應的目錄下運行服務端和客戶端,結果如下:
    服務端:
    在這里插入圖片描述
    客戶端:
    在這里插入圖片描述

    接下來是net.server和net.socket的其中一些介紹:

    服務端 net.Server

    server.close(callback])
    關閉服務器,停止接收新的客戶端請求。有幾點注意事項:

    • 對正在處理中的客戶端請求,服務器會等待它們處理完(或超時),然后再正式關閉。
    • 正常關閉的同時,callback 會被執行,同時會觸發 close 事件。
    • 異常關閉的同時,callback 也會執行,同時將對應的 error 作為參數傳入。(比如還沒調用 server.listen(port) 之前,就調用了server.close())

    結論:

    • 已調用server.listen():正常關閉,close事件觸發,然后callback執行,error參數為undefined
    • 未調用server.listen():異常關閉,close事件觸發,然后callback執行,error為具體的錯誤信息。(注意,error 事件沒有觸發)

    server.ref()/server.unref()
    主要用于將server 加入事件循環/從事件循環里面剔除,區別就在于會不會影響進程的退出。

    事件 listening/connection/close/error

    • listening:調用 server.listen(),正式開始監聽請求的時候觸發。
    • connection:當有新的請求進來時觸發,參數為請求相關的 socket。
    • close:服務端關閉的時候觸發。
    • error:服務出錯的時候觸發,比如監聽了已經被占用的端口。

    客戶端 net.Socket

    連接相關

    • socket.connect():有3種不同的參數,用于不同的場景;
    • socket.setTimeout():用來進行連接超時設置。
    • socket.setKeepAlive():用來設置長連接。
    • socket.destroy()、socket.destroyed:當錯誤發生時,用來銷毀socket,確保這個socket上不會再有其他的IO操作。

    數據讀、寫相關
    socket.write()、socket.end()、socket.pause()、socket.resume()、socket.setEncoding()、socket.setNoDelay()

    數據屬性相關
    socket.bufferSize、socket.bytesRead、socket.bytesWritten

    事件循環相關
    socket.ref()、socket.unref()

    緊接著也嘗試做了一個簡單的問答精靈的例子,加深理解:
    服務端:

    const net =require('net');
    const users ={};
    
    const server = net.createServer((socket)=>{
    	socket.write(`聊天服務支持的指令有:
    	1、注冊用戶 {"cmd":"addUser","content":"要注冊的用戶名"}
    	2、發送私信 {"cmd":"privateMessage","toUser":"接收消息的用戶名","content":"消息內容"}
        3、群發消息 {"cmd":"all","content":"消息內容"}
    	`);
    	let currentUserName;
    	socket.on("data",(data)=>{
    		//先把發過來的buffer數據轉成json
    		try{
    			JSON.parse(data.toString());
    		}
    		catch(e){
    			socket.write("消息格式錯誤,請重試!");
    			return;
    		}
    		var json = JSON.parse(data.toString());
    		switch(json.cmd){
    			case 'addUser':
    				//判斷該用戶是否重名
    				for(var key in users){
    					if(key == json.content){
    						socket.write('用戶名已被注冊,請重試');
    						return;
    					}
    				}
    				users[json.content] = socket;
    				currentUserName = json.content;
    				socket.write(`恭喜${json.content}用戶注冊成功`);
    				break;
    			case 'privateMessage':
    				//判斷你要聯系的用戶是否存在
    				for(var key in users){
    					if(key == json.toUser){
    						//用戶存在
    						users[json.toUser].write(`${currentUserName}:${json.content}`);
    						return;
    					}
    				}
    				socket.write(`用戶${json.toUser}不存在`);
    				break;
    			case 'all':
    				//群發
    				for(var key in users){
    					if(key == currentUserName){
    						continue;
    					}
    					users[key].write(`${currentUserName}@所有人:${json.content}`);
    				}
    			default:
    				break;
    		}
    	})
    });
    
    server.listen(8888,()=>{
    	console.log('問答精靈服務器已經開啟在8888端口')
    })
    
    

    客戶端:

    const net =require("net");
    const socket = net.createConnection(8888,"電腦ip地址",()=>{
    	console.log('已經成功進入問答精靈聊天室');
    })
    
    socket.on("data",(data)=>{
    	console.log(data.toString());
    })
    process.stdin.resume();
    process.stdin.setEncoding("utf8");
    process.stdin.on("data",(data)=>{
    	if(data.toString().startsWith('add:')){
    		let dataString = data.toString(); 
    		//截取空格
    		let content = dataString.substring(dataString.indexOf(':')+1,dataString.length-2); 
    		data=`{"cmd":"addUser","content":"${content}"}`;
    //		console.log(data);
    	}
    	else if(data.toString().startsWith('@all:')){
    		let dataString = data.toString();
    		let content = dataString.substring(dataString.indexOf(':')+1,dataString.length-2); 
    		data=`{"cmd":"all","content":"${content}"}`;
    	}
    	else if(data.toString().startsWith('@')){
    		let dataString = data.toString();
    		let parts = dataString.split(":");
    		let to = parts[0].substring(1);
    		let content = parts[1].substring(0,parts[1].length-2);
    		data=`{"cmd":"privateMessage","toUser":"${to}","content":"${content}"}`;
    	}
    	socket.write(data);
    })
    

    結果:
    在這里插入圖片描述

    官方文檔

    更多詳情可參考官方文檔

    版權聲明:本文為weixin_44987155原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/weixin_44987155/article/details/89607430

    智能推薦

    Nodejs學習筆記——http模塊搭建簡易服務器

    開啟一個本地服務器需要Node.js中http核心模塊 引入模塊 實例 案例1: 案例2:...

    NodeJs 的fs模塊

    <1>js 里面的fs模塊 readFile(),readFileSync() writeFile(),writeFileSync() exists(path, callback) mkdir(),writeFile(),readFile() mkdirSync(),writeFileSync(),readFileSync() readdir(),readdirSync() stat(...

    nodeJs高階模塊--fs

    請問大家: NodeJs只能做的兩件事是什么? 這也能做,那也能做~ just joke~ 實際上,所有后臺語言都能做的兩件事是: 文件操作和網絡編程. 這其實是所有語言的根本。 計算機無外乎就是文件和通信。Linux中,是把一切都當做文件,如果理解了這一點那就無可厚非了. 所以,這里,我想介紹一下NodeJS中一個重要的模塊--fs. 這里我給大家放一個我的框架圖~ (為什么不是http? 懶~...

    nodejs發布模塊

    nodejs安裝目錄:D:\soft\nodejs 新建js文件:例如:HelloWorld.js--->console.log("hello world!"); 1.創建一個新的模塊 name:wx_ll 2.注冊npm賬號 3.上傳包4.安裝包5.管理包權限6.分析包 7.使用引入包     ...

    HTML中常用操作關于:頁面跳轉,空格

    1.頁面跳轉 2.空格的代替符...

    猜你喜歡

    freemarker + ItextRender 根據模板生成PDF文件

    1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...

    電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!

    Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...

    requests實現全自動PPT模板

    http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...

    Linux C系統編程-線程互斥鎖(四)

    互斥鎖 互斥鎖也是屬于線程之間處理同步互斥方式,有上鎖/解鎖兩種狀態。 互斥鎖函數接口 1)初始化互斥鎖 pthread_mutex_init() man 3 pthread_mutex_init (找不到的情況下首先 sudo apt-get install glibc-doc sudo apt-get install manpages-posix-dev) 動態初始化 int pthread_...

    精品国产乱码久久久久久蜜桃不卡