一、安裝Nodejs
1下載安裝node.js
下載安裝:地址址http://www.nodejs.cn
使用node.exe來(lái)解釋執(zhí)行 寫(xiě)好的js代碼
環(huán)境變量他會(huì)自動(dòng)配置好
但是你使用第三庫(kù)就還要一個(gè)環(huán)境變量,指定Node搜索第三方模塊路勁
NODE_PATH是npm安裝好的模塊所在的搜索路勁.
NODE_PATH 值: %AppData%\npm\node_modules;
2.下載安裝cygwin 然后 寫(xiě)一個(gè)hello
找打這個(gè)js文件目錄
node js文件名 解釋執(zhí)行即可
二、事件循環(huán)和progress模塊
Node.js事件循環(huán)
1.如果node.js沒(méi)有要處理的事件了,那整個(gè)就結(jié)束.直接退出node
事件里面可以繼續(xù)插入事件,如果有事件是一直要繼續(xù)下去
那node就不會(huì)退出,每一次事件處理結(jié)束后,等待下一個(gè)事件的發(fā)生
一旦有事件發(fā)生就會(huì)調(diào)用回調(diào)函數(shù).回調(diào)函數(shù)里還可以插入新的事件
2setTimeout插入一個(gè)計(jì)時(shí)器事件,單位為毫秒 觸發(fā)一次結(jié)束.
setTimeout(function() { console.log("hello world"); },3000);
3setInterval插入一個(gè)不斷循環(huán)的計(jì)時(shí)器事件.
setInterval(function () { console.log("hello world"); },1000*2);
Progress屬性和事件
1.process模塊用來(lái)與當(dāng)前進(jìn)程互動(dòng),獲取相關(guān)操作系統(tǒng)相關(guān)信息
2.process是全局模塊 全局變量不需要require
3.process.pid進(jìn)程pid,version是node版本,platform平臺(tái),
title窗口或進(jìn)程名稱,argv控制臺(tái)啟動(dòng)傳入的參數(shù),他是個(gè)字符串?dāng)?shù)組
execPath,node所在路勁, env獲得系統(tǒng)的環(huán)境變量
重要方法
cwd 獲取當(dāng)前工作目錄 uptime獲取進(jìn)程運(yùn)行時(shí)間,
chdir這只當(dāng)前的工作目錄 ,
nextTick下一次循環(huán)的時(shí)候調(diào)用后沒(méi)事循環(huán)事件開(kāi)始前先調(diào)用它
4.監(jiān)聽(tīng)exit事件,node退出會(huì)拋出exit事件,當(dāng)用戶監(jiān)聽(tīng)這個(gè)事件
那么exit事件發(fā)生后會(huì)收到通知.
process.on("exit",function(){ console.log("node退出"); });
5.uncaughtException事件function(err){};
6.處理的時(shí)候遇到了異常,如果這個(gè)異常捕獲,那么就繼續(xù)
處理下一個(gè)事件,則否直接停止.
//沒(méi)有定義的函數(shù) 調(diào)用 //解釋器 不會(huì)主動(dòng)捕獲異常,他就不會(huì)繼續(xù)執(zhí)行 notfunction();
捕獲異常 這樣node就不會(huì)終止運(yùn)行,
//當(dāng)有異常發(fā)生 立刻調(diào)用這個(gè)回調(diào)函數(shù) process.on("uncaughtException",function(err){ console.log("捕獲到異常:"+err); });
三、Node.js Net模塊使用TCP通訊
在node.js里所有的net模塊 都是異步的,所以都要通過(guò)
綁定事件,來(lái)獲取相應(yīng)的操作是否完成.
server服務(wù)器
只要?jiǎng)?chuàng)建一個(gè)監(jiān)聽(tīng)服務(wù)器,然后調(diào)用監(jiān)聽(tīng)函數(shù)即可
每次有新的連接產(chǎn)生后就調(diào)用connection事件
他的參數(shù)就是和客戶端通信的socket一個(gè)net.Socket實(shí)例
這個(gè)實(shí)例里就要綁定 error錯(cuò)誤事件,close客戶端關(guān)閉事件
還有就是data客戶端發(fā)送數(shù)據(jù)的事件,這個(gè)事件發(fā)送的數(shù)據(jù)
默認(rèn)參數(shù)data是二進(jìn)制的,你要調(diào)用setEncoding設(shè)置編碼
//引入net模塊 var net = require("net"); //創(chuàng)建一個(gè)net.Server用來(lái)監(jiān)聽(tīng) //這個(gè)API是創(chuàng)建一個(gè)新的TCP或IPC服務(wù)。 //當(dāng)有連接請(qǐng)求 會(huì)調(diào)用這個(gè)匿名回調(diào)函數(shù) var server = net.createServer((client_sock)=>{ //收到客戶端接入的回調(diào)函數(shù) //client_spcl就是與客戶端通訊的socket console.log("client comming"); }); //指示監(jiān)聽(tīng)端口 為 connections 啟動(dòng)一個(gè) server 監(jiān)聽(tīng) //server.listen(options[, callback]) //這個(gè)函數(shù)是異步的,server開(kāi)始監(jiān)聽(tīng),listening事件觸發(fā), //最后一個(gè)參數(shù)callback就是listening事件監(jiān)聽(tīng)器. //如果 exclusive 是 false(默認(rèn)), //則集群的所有進(jìn)程將使用相同的底層句柄, //允許共享連接處理任務(wù) node事件循環(huán)會(huì)一直等待在這 console.log("開(kāi)始等待客戶端連接"); server.listen({ host: "127.0.0.1", //host: 'localhost', port: 6800, exclusive: true, }); //綁定listening 事件 //當(dāng)服務(wù)被綁定后調(diào)用 也就是調(diào)用listen函數(shù)就調(diào)用 server.on("listening",function(){ console.log("start listening ..."); }); //綁定建立鏈接事件 和客戶端不同 //這個(gè)會(huì)產(chǎn)生一個(gè)net.Socket新的實(shí)例 //用來(lái)和客戶端產(chǎn)生通訊的 上面那個(gè) 就是這個(gè)參數(shù) //其實(shí)就是封裝了這個(gè)事件 的回調(diào)函數(shù) server.on("connection",function(client_sock){ console.log("新的鏈接建立了"); //綁定 客戶端socket 關(guān)閉 事件 client_sock.on("close",function(){ console.log("客戶端關(guān)閉連接"); }); //設(shè)置 接受數(shù)據(jù)的編碼 //data默認(rèn)是二進(jìn)制格式、 //這個(gè)二進(jìn)制每一個(gè)值 對(duì)應(yīng)ASCLL碼的十六進(jìn)制值 //調(diào)用這個(gè)底層就將他轉(zhuǎn)出成utf8的字符串 //然后傳給你 //設(shè)置成二進(jìn)制 //client_sock.setEncoding("hex"); //這樣會(huì)把這個(gè)Buffer對(duì)象轉(zhuǎn)成二進(jìn)制字符串給你 client_sock.setEncoding("utf-8"); ////當(dāng)客戶端給 服務(wù)器發(fā)數(shù)據(jù)的時(shí)候 //綁定data事件 當(dāng)接收到數(shù)據(jù)時(shí)被觸發(fā) //參數(shù)data是buffer或者string類型 //數(shù)據(jù)的編碼由socket.setEncoding()設(shè)定 client_sock.on("data",function(data){ console.log("接收到數(shù)據(jù)",data); }); //監(jiān)聽(tīng)錯(cuò)誤事件 通訊可能會(huì)出錯(cuò) client_sock.on("error",function(e){ console.log("error",e); }); }); //綁定錯(cuò)誤事件 server.on("error",function(){ console.log("listener err"); }); //綁定關(guān)閉事件 server.on("close",function(){ //服務(wù)器關(guān)閉 如果還有鏈接存在,直到所有連接關(guān)閉 //這個(gè)事件才會(huì)被觸發(fā) console.log("server stop listener"); }); //停止偵聽(tīng) 連接 // server.unref(); //停止監(jiān)聽(tīng) 主動(dòng)關(guān)閉socket //參數(shù) 就是close事件的回調(diào) 可以寫(xiě)在參數(shù)里都可以 //他必須是在停止偵聽(tīng)之后 調(diào)用 //如果不這樣的話 服務(wù)器 還是可以收到連接 //server.close();
Client客戶端
首先用ner.creatConnection或者net.connect創(chuàng)建連接到服務(wù)器
這時(shí)候你就要綁定connect的回調(diào)函數(shù),一旦連接成功就會(huì)回調(diào)
close事件,socket關(guān)閉后觸發(fā), data事件,收到數(shù)據(jù)就觸發(fā)
error事件,當(dāng)socket有錯(cuò)誤發(fā)生.
//引入net模塊 var net = require("net"); //鏈接服務(wù)器 一旦鏈接成功第二個(gè)參數(shù) //就會(huì)立刻回調(diào) var c_sock = net.connect({ port:6800, host:"127.0.0.1", },()=>{ console.log("connected to server!"); }); //這里綁定connect事件 和上面那個(gè)效果相同 //上面那個(gè)是 被封裝成回調(diào)函數(shù)了 c_sock.on("connect",function(){ console.log("connect success!"); //socket.write(data,[,encoding][,callback]) //在socket上發(fā)送數(shù)據(jù),第二個(gè)參數(shù)指定字符串編碼默認(rèn)UTF-8 //如果發(fā)數(shù)據(jù)成功到內(nèi)核的緩沖返回true,如果全部或部分 //數(shù)據(jù)在用戶內(nèi)中排隊(duì),返回false,如果緩沖再次空閑則觸發(fā) //drain事件, 當(dāng)數(shù)據(jù)最終寫(xiě)出之后,調(diào)用callback回調(diào). //第二個(gè)參數(shù) 和 第三個(gè)參數(shù)是可選的 c_sock.write("hello socket server"); }); //綁定錯(cuò)誤事件 c_sock.on("error",function(err){ console.log("錯(cuò)誤"+err); }); //綁定關(guān)閉事件 c_sock.on("close",function(){ console.log("關(guān)閉socket"); });
四、Node.js二進(jìn)制數(shù)據(jù)和Buffer模塊
在網(wǎng)絡(luò)數(shù)據(jù)的傳送過(guò)程中,所有的數(shù)據(jù)都是使用二進(jìn)制傳送的.
二進(jìn)制
1.在計(jì)算機(jī)里存放的數(shù)據(jù)都是二進(jìn)制的方式來(lái)存儲(chǔ)
2.最小單位為字節(jié),8位二進(jìn)制-->bit
3.所有數(shù)據(jù)最終都是二進(jìn)制的方式存放;
4.比如說(shuō)你有一個(gè)字符串"ABCD" 因?yàn)檫@是幾個(gè)英文單詞,但是
無(wú)法直接把這個(gè)幾個(gè)單詞存到電腦里面,因?yàn)殡娔X只認(rèn)識(shí)二進(jìn)制的
0和1,這時(shí)候就要用到編碼,用特定的數(shù)字表示特定的符號(hào).
4.ASCLL編碼,'A'-->65數(shù)據(jù),把數(shù)據(jù)當(dāng)字符,
也就是把字符A轉(zhuǎn)出一個(gè)數(shù)據(jù)65,然后把65存進(jìn)去.
5.
Int8/Uint8 一個(gè)字節(jié)的整數(shù)
Int16/Uint16 二個(gè)字節(jié)的整數(shù)
Int32/Uint32 4個(gè)字節(jié)的整數(shù)
Int/Uint 8個(gè)字節(jié)整數(shù)
Float4個(gè)字節(jié)小數(shù), Double 8個(gè)字節(jié)的小數(shù);
大尾和小尾
1.兩個(gè)字節(jié)0x7766其中 77是高位,66是低位
2.尾指定是地址是低的地方,
3.小尾Lihe指的是低位的數(shù)據(jù)存在低地址的地方,高位存放在高地址的地方
4.大尾Bigger指的是高位的數(shù)據(jù)存在低地址的地方,低位存在在高地址的地方
5.計(jì)算機(jī)中的內(nèi)存使用的就是小尾. 有的CPU則使用大尾.
6.4個(gè)字節(jié)的數(shù)據(jù),存到內(nèi)存的4個(gè)字節(jié)
小尾: LE高位的數(shù)據(jù)-->高地址字節(jié)的地方==高高低低
大尾: BE高位的數(shù)據(jù)-->地地址字節(jié)的地方==低高低高
Buffer Pool
1.node.js使用Buffer對(duì)象來(lái)存放二進(jìn)制數(shù)據(jù);
2.為了快速分配,先從Buffer池分配,如果分配不成功,再直接
向系統(tǒng)申請(qǐng) Buffer pool 只能滿足一定范圍內(nèi)的大小,
如過(guò)你申請(qǐng)的過(guò)大,那么他會(huì)直接向操作系統(tǒng)申請(qǐng)內(nèi)存.
3.Buffer pool是為了提高內(nèi)存分配的效率和利用率.
一些小內(nèi)存首先會(huì)從Buffer pool里分配,分配成功直接返回這個(gè)內(nèi)存
如果分配不成功,再向操作系統(tǒng)去申請(qǐng),回收的時(shí)候直接丟給操作系統(tǒng).
4.Buffer就為我們提供了,大小不大,但是分配頻繁的內(nèi)存,
做了一個(gè)緩存池,提高運(yùn)行效率. 減少內(nèi)存碎片.
5.創(chuàng)建一個(gè)Buffer對(duì)象 Buffer一旦分配大小,再也無(wú)法改變
如果這時(shí)候你使用越界,就會(huì)出現(xiàn)錯(cuò)誤.
length屬性獲取Buffer對(duì)象的長(zhǎng)度.
Buffer.alloc(); Buffer.allocUnsafe();Buffer.allocUnsafeSlow()
Buffer.from(array),Buffer.from(buf),Buffer.from(string)
//(1)分配10個(gè)字節(jié) //(2)會(huì)給這些內(nèi)存一個(gè)初值,如果你每指定, //那么這個(gè)初值就是0 //41十六進(jìn)制從ASCLL碼的41表示A ////輸出十個(gè) "41" 41是十六進(jìn)制 var buf = Buffer.alloc(10,'A'); //這樣也可以 代表十六進(jìn)制 41 //輸出十個(gè) "41" 41是十六進(jìn)制 buf = Buffer.alloc(10,0x41); //也可以是字符串 buf = Buffer.alloc(10,"Hell"); /////////Unsafe //(1)他會(huì)分配一個(gè)給定大小的Buffer內(nèi)存 //(2)不會(huì)對(duì)這些內(nèi)存去賦初值的. //這個(gè)內(nèi)存是隨機(jī)的數(shù)據(jù) buf = Buffer.allocUnsafe(10); /////////UnsafeSlow //沒(méi)有從緩沖池里面高效的分配 //直接從操作系統(tǒng)分配,更慢所以叫Slow //Unsafe 是沒(méi)有初始化的內(nèi)存 buf = Buffer.allocUnsafeSlow(10); //獲得Buffer對(duì)象的長(zhǎng)度 console.log(buf.length); /////////from(string) //更方便的創(chuàng)建方式類似于復(fù)制 //分配一個(gè)BUffer對(duì)象,用來(lái)存放字符串的二進(jìn)制. //輸出結(jié)果是每個(gè)字母對(duì)應(yīng)的十六進(jìn)制ASCLL碼 buf = Buffer.from("HelloWorld"); ////////from(array) //輸出的是每個(gè)數(shù)字十進(jìn)制,對(duì)應(yīng)的十六進(jìn)制 buf = Buffer.from([123,456,789,-1,45]); //////from(Buffer) //重新場(chǎng)景一個(gè)Buffer把原來(lái)buf的數(shù)據(jù)拷貝給新的 var buf2 = Buffer.from(buf); console.log(buf2); /////讀取其中的一個(gè)數(shù)據(jù) //輸出的是123 console.log(buf[0]); console.log(buf);
讀寫(xiě)B(tài)uffer
1.Buffer讀取字節(jié)buf[index]使用下標(biāo)
這個(gè)索引是 0 到 length - 1,才是合法范圍.
2.根據(jù)大大尾小尾來(lái)決定使用BE大尾/LE小尾
3.readFloatBE/readDoubleBE/readFloatLE/readDoubleLE
4.讀/寫(xiě)整數(shù):read/write
Int8/Uint 一個(gè)字節(jié)不存在大尾小尾.
Int16BE/Int16LE/UInt16BE/UInt16LE
Int32BE/Int32LE/UInt32BE/UInt32LE
IntBE/IntLE/UIntBE/UIntLE
floatBE/floatLE/doubleBE/doubleLE
寫(xiě)一個(gè)整數(shù)到Buffer里面
//寫(xiě)入4個(gè)字節(jié) 大尾 //value值,offset是從哪開(kāi)始寫(xiě) //noAssert是否檢查長(zhǎng)度是不是有效范圍, //用來(lái)檢測(cè)內(nèi)存越界,默認(rèn)不用檢測(cè),提升性能. //writeInt32LE(value,offset,[.noAssert]) buf.writeInt32BE(65535,0); //用十六進(jìn)制表示 0x0000ffff //這里輸出的就是00 00 FF FF //因?yàn)樗谴笪卜▽?xiě)入,他的高位0000 低位FFFF //大端法 大尾把高位放低地址作為起始地址 //所以輸出的就是 00 00 FF FF console.log(buf);
讀取
//使用大尾讀出來(lái) 參數(shù)是從哪里開(kāi)始讀 var value = buf.readInt32BE(0); console.log(value);
Buffer重要方法
1.Buffer.byteLength(str,encoding)返回字符對(duì)象
str可以說(shuō)string,Buffer,Array,ArrayBuffer
對(duì)應(yīng)的二進(jìn)制長(zhǎng)度.encoding如果是字符串,字符編碼模式utf-8
也就是存下str需要多長(zhǎng)字節(jié).
var len = Buffer.byteLength("HelloWorld"); //輸出10 console.log(len); 也可以是Buffer對(duì)象 var len = Buffer.byteLength(buf2); //輸出5 console.log(buf2);
2.交換swap16,swap32,swap64 大尾小尾數(shù)據(jù)變化
16是兩個(gè)字節(jié)交換位置, 32是4個(gè)字節(jié)兩個(gè)兩個(gè)交換位置
64是前面4個(gè)和后面4個(gè)字節(jié) 交換位置
將buf解析為一個(gè)整數(shù)數(shù)組,并且以字節(jié)順序原地進(jìn)行交換
//16個(gè)字節(jié) var bufer = Buffer.alloc(4*4); bufer.writeInt32LE(65535,0); bufer.writeInt32LE(65535,4); bufer.writeInt32LE(65535,8); bufer.writeInt32LE(65535,12); //輸出ffff0000 4個(gè) //并且是小尾 存放 console.log(bufer);
然后轉(zhuǎn)換成大尾
bufer.swap32(); //這里輸出的就是0000 ffff 4個(gè) //就是轉(zhuǎn)換成大端法,高位放地地址. console.log(bufer);
3.buffer.values() 遍歷buf每個(gè)字節(jié)
for(var vlu of bufer.values()) { console.log(vlu); }
4.Buffer轉(zhuǎn)字符串 buf.toString()
比如說(shuō)二進(jìn)制字符串
//參數(shù) 是編碼 hex是二進(jìn)制 console.log(bufer.toString('hex'));
5.Buffer轉(zhuǎn)Json字符串,
JSON.stringify(buf) buffer.toJSON
console.log(bufer.toJSON());
6.Buffer.fill 填充參數(shù)可以是字符 字符串 ×××
那這個(gè)buffer里所有數(shù)據(jù)都變成這個(gè)了
bufer.fill(23);
bufer.fill("ab")
如果未指定 offset
和 end
,則填充整個(gè) buf
。
這個(gè)簡(jiǎn)化使得一個(gè) Buffer
的創(chuàng)建與填充可以在一行內(nèi)完成
例如填充ASCLL碼 'A'
bufer.fill('A');
console.log(bufer);
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。
網(wǎng)頁(yè)題目:Node.js服務(wù)器開(kāi)發(fā)(1)-創(chuàng)新互聯(lián)
文章鏈接:http://www.rwnh.cn/article38/jhppp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供全網(wǎng)營(yíng)銷推廣、靜態(tài)網(wǎng)站、自適應(yīng)網(wǎng)站、外貿(mào)網(wǎng)站建設(shè)、企業(yè)網(wǎng)站制作、定制開(kāi)發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容