摘要:創(chuàng)建服務(wù)器方法返回被創(chuàng)建的服務(wù)器參數(shù)參數(shù)值為一個對象可以在給兌現(xiàn)各種使用一個布爾類型的屬性當(dāng)為時當(dāng)服務(wù)器接收到客戶端發(fā)送的一個包時將會回發(fā)一個包當(dāng)為時服務(wù)器接收到客戶端發(fā)送的包時不回發(fā)包這使得服務(wù)器可以繼續(xù)向客戶端發(fā)送數(shù)據(jù)但是不會繼續(xù)接收客
1.創(chuàng)建TCP服務(wù)器
let server = net.createServer([options], [connectionListener]);
createServer方法返回被創(chuàng)建的TCP服務(wù)器
options參數(shù)
options參數(shù)值為一個對象,可以在給兌現(xiàn)各種使用一個布爾類型的allowHalfOpen屬性,當(dāng)為false時,當(dāng)TCP服務(wù)器接收到客戶端發(fā)送的一個FIN包時將會回發(fā)一個FIN包.當(dāng)為true時,TCP服務(wù)器接收到客戶端發(fā)送的FIN包時不回發(fā)FIN包,這使得TCP服務(wù)器可以繼續(xù)向客戶端發(fā)送數(shù)據(jù),但是不會繼續(xù)接收客戶端發(fā)送的數(shù)據(jù),必須調(diào)用end方法來關(guān)閉該socket連接.
connectionListener參數(shù)用于指定客戶端與服務(wù)器端建立起來時所要調(diào)用的回調(diào)函數(shù).
const net = require("net"); let server = net.createServer(false, function (socket) {});2. 建立連接
當(dāng)客戶端與服務(wù)器建立連接時,觸發(fā)connection事件,我們可以通過對connection事件進(jìn)行監(jiān)聽,并且指定該事件的返回函數(shù)的方法來指定當(dāng)客戶端與服務(wù)器建立連接時所需要執(zhí)行的處理
server.on("connection", function(socket){})
回調(diào)函數(shù)中的參數(shù)為該TCP服務(wù)器監(jiān)聽的socktet端口對象
在創(chuàng)建了TCP服務(wù)器之后,可以用listen方法通知服務(wù)器開始監(jiān)聽客戶端連接,有三種指定的方法
2.1 listen方法一:server.listen(port, [host], [backlog], [callback]);
port為必須要指定的參數(shù),為0時將為TCP分配一個隨機(jī)端口號.
host為指定需要監(jiān)聽的IP地址或主機(jī)名,如果省略,服務(wù)器將錦亭來自任何IPv4地址的客戶端連接
backlog為一個整數(shù)值,用于指定位于等待隊(duì)列中的客戶端連接的最大數(shù)量,一旦超過這個長度,TCP服務(wù)器將開始拒絕來自新的客戶端的連接請求,參數(shù)值默認(rèn)為511
當(dāng)對TCP服務(wù)器制定了需要監(jiān)聽的地址和端口后,服務(wù)器將立即開始監(jiān)聽來自于該地址及端口的客戶端連接,這時觸發(fā)該服務(wù)器的listening事件,可使用listen方法的callback參數(shù)來指定listening事件觸發(fā)時調(diào)用的回調(diào)函數(shù),該回調(diào)函數(shù)中不使用任何參數(shù)
2.2 listen方法二:server.listen(path, [callback]);
這種形式的listen方法用于通知一個使用unix端口的服務(wù)器開始監(jiān)聽來自于路徑的客戶端連接.
path為指定的需要監(jiān)聽的路徑,當(dāng)對使用unix端口的服務(wù)器指定了需要監(jiān)聽的路徑后,服務(wù)器將立即開始監(jiān)聽來自于該路徑的客戶端連接.
這時觸發(fā)該服務(wù)器的listening事件,可以使用listen方法的callback參數(shù)來指定listening事件觸發(fā)時調(diào)用的回調(diào)函數(shù),該回調(diào)函數(shù)不需要使用任何參數(shù).
2.3 listen方法三:server.listen(handle, [callback]);
這種形式的listen方法用于通知一個TCP服務(wù)器開始監(jiān)聽一個指定socket句柄的客戶端來接該方法使用兩個參數(shù)
(該句柄可以為一個TCP服務(wù)器對象,也可以為一個文件描述符,在WINDOWS操作系統(tǒng)中不支持對文件描述符的監(jiān)聽)
第一個參數(shù)用于執(zhí)行需要監(jiān)聽的socket句柄.當(dāng)對TCP服務(wù)器指定了需要監(jiān)聽的socket句柄后,服務(wù)器端將立即開始監(jiān)聽來自于該socket句柄的客戶端連接,這時觸發(fā)該服務(wù)器的listening事件
可以使用listen方法的callback參數(shù)來指定listening事件觸發(fā)時調(diào)用的回調(diào)函數(shù),該回調(diào)函數(shù)不需要任何參數(shù).
如果不在上述三種形式的listen方法中使用callback參數(shù),可以通過監(jiān)聽TCP服務(wù)器對象的listening事件,并且指定該事件觸發(fā)時調(diào)用的回調(diào)函數(shù)的方法來指定TCP服務(wù)器開始監(jiān)聽時所需要執(zhí)行的處理server.on("listening", function(){})
3. error對TCP服務(wù)器指定需要監(jiān)聽的地址及端口時,如果該地址及端口已經(jīng)被占用,將產(chǎn)生一個錯誤代碼為EADDRINUSE的錯誤(表示用于監(jiān)聽的地址和端口被占用),同是將觸發(fā)TCP服務(wù)器一個error事件,可以通過對error事件設(shè)置回調(diào)函數(shù)的方法指定該錯誤產(chǎn)生時需要執(zhí)行的處理.
const net = require("net"); let server = net.createServer(false, function (socket) { // 這里的socket參數(shù)就是一個socket對象 }); server.on("error", function (e) { if (e.code === "EADDRINUSE") { console.log("該地址及端口被占用,請修正") } });4. address
創(chuàng)建了TCP服務(wù)器之后,可以是使用TCP服務(wù)器的address方法來查看該服務(wù)器所監(jiān)聽的地址信息
let address = server.address();
該方法返回一個對象,其中具有以下的屬性
port:TCP服務(wù)器監(jiān)聽的socket端口號
address:TCP服務(wù)器監(jiān)聽的地址,如127.0.0.1
family:一個標(biāo)識了TCP服務(wù)器所監(jiān)聽的地址的是IPv4地址還是IPv6地址的字符串,例如IPv4
使用TCP服務(wù)器的getConnections方法查看當(dāng)前與TCP服務(wù)器建立連接的客戶端連接數(shù)量server.getConnections(callback(err, count))
TCP服務(wù)器server對象的maxConnections屬性將TCP對象的最大連接數(shù)設(shè)置為2,同時在控制臺中輸出設(shè)置后的maxConnections屬性值,當(dāng)當(dāng)前客戶端與服務(wù)器連接數(shù)等于該值時,不再接受新的客戶端連接請求.
5. close每當(dāng)有客戶端與服務(wù)器端建立連接后,第一個命令行窗口中都將顯示當(dāng)前存在的客戶端與TCP服務(wù)器之間的連接數(shù)量.
在一個新的命令行窗口中建立與被創(chuàng)建的TCP服務(wù)器之間的連接,TCP服務(wù)器將不再接收該連接,第一個命令行窗口中不會有任何變化.
可以使用TCP服務(wù)器的close方法顯式指定服務(wù)器拒絕所有新的客戶端連接
server.close([callback()])
在使用close方法時,并不會斷開所有現(xiàn)存的客戶端連接.當(dāng)這些客戶端連接被關(guān)閉時,TCP服務(wù)器將會自動關(guān)閉,同時觸發(fā)TCP服務(wù)器的close事件,close的回調(diào)函數(shù)是否有參數(shù)都可以.
6. socket端口對象在Node.js中,使用net.Socket代表一個socket端口對象,在使用createServer方法的connectionListener參數(shù)所指定的回調(diào)函數(shù)(當(dāng)客戶端與服務(wù)器端建立連接時調(diào)用)的參數(shù)值,即為一個被自動創(chuàng)建的net.Socket對象(代表的服務(wù)器所監(jiān)聽的端口對象),在對TCP服務(wù)器所指定的connection事件回調(diào)函數(shù)的參數(shù)值同樣為一個被自動創(chuàng)建的net.Socket對象(代表TCP服務(wù)器所監(jiān)聽的端口對象)
與TCP服務(wù)器獨(dú)享的address方法相類似,可以利用socket端口對象的address方法獲取該socket端口對象相關(guān)的地址信息
let address = socket.address();
該方法返回一個對象,其中具有以下的屬性
port:TCP服務(wù)器監(jiān)聽的socket端口號
address:TCP服務(wù)器監(jiān)聽的地址,如127.0.0.1
family:一個標(biāo)識了TCP服務(wù)器所監(jiān)聽的地址的是IPv4地址還是IPv6地址的字符串,例如IPv4
socket端口對象可被用來讀取客戶端發(fā)送的流數(shù)據(jù),每次接收到客戶端發(fā)送的流數(shù)據(jù)時觸發(fā)data事件,可通過對該事件進(jìn)行監(jiān)聽并且指定回調(diào)函數(shù)的方法來指定當(dāng)服務(wù)器端監(jiān)聽的socket端口對象接收到客戶端發(fā)送的數(shù)據(jù)時所需要執(zhí)行的處理.
socket.on("data", function (data) {});
在該回調(diào)函數(shù)中,使用給一個參數(shù),參數(shù)值為一個Buffer對象(在未使用socket端口對象的setEncoding方法指定編碼時)或者一個字符串對象(在使用socket端口對象的setEncoding方法指定編碼方式后)
data獲取到的是一個存放了服務(wù)到的數(shù)據(jù)的緩存區(qū)對象,如果我們在對data事件進(jìn)行監(jiān)聽之后使用編碼格式,將在控制臺中以字符串形式輸出讀取到的數(shù)據(jù).
const net = require("net"); let server = net.createServer(false, function (socket) { socket.setEncoding("utf8"); socket.on("data", function (data) { console.log(data); }); });6.2 方法二:
const net = require("net"); let server = net.createServer(false, function (socket) { socket.on("data", function (data) { console.log(data.toString()); }); });7. pipe
可以通過socket對象的pipe方法將客戶端發(fā)送的流數(shù)據(jù)寫到文件等其他目標(biāo)對象中
socket.pipe(destination, [options]);
destination參數(shù)為必須輸入?yún)?shù),options參數(shù)為可選參數(shù).destination參數(shù)值必須為一個可用于寫入流數(shù)據(jù)的對象.options參數(shù)值為一個對象,可以在該對象中使用一個布爾類型的end屬性,如果該屬性值為true,則當(dāng)數(shù)據(jù)全被讀取完畢時立即結(jié)束寫操作,如果該屬性值為false,目標(biāo)對象中可以被繼續(xù)寫入新的數(shù)據(jù),該屬性的默認(rèn)值為true;
const net = require("net"); let file = require("fs").createWriteStream("./message.txt"); let server = net.createServer(); server.on("connection", function (socket) { socket.pipe(file, { end: false }); socket.on("end", function () { file.end("byebye"); }); }); server.listen(9999, "localhost");
使用unpipe方法取消目標(biāo)對象的寫入操作
socket.unpipe([destination]);8. pause
可以使用socket端口對象的pause方法暫停data事件的觸發(fā),這時服務(wù)器端將把每一個客戶端發(fā)送的數(shù)據(jù)暫存在一個多帶帶的緩存區(qū)中.
socket.pause();
在使用了pause方法暫停data事件的觸發(fā)后,可以使用socket端口對象的resume方法恢復(fù)data事件的觸發(fā),這時將讀取被緩存的該客戶端的數(shù)據(jù).
socket.resume();
通過監(jiān)聽socket端口對象的timeout事件并且指定該事件回調(diào)函數(shù)的方法來指定當(dāng)客戶端連接超時時所需要執(zhí)行的處理
const net = require("net"); let server = net.createServer(); server.on("connection", function (socket) { socket.setTimeout(10 * 1000); socket.pause(); socket.on("timeout", function () { socket.resume(); socket.pipe(file); }); socket.on("data", function (data) { socket.pause(); }); });10. 一個基本的TCP服務(wù)器
const net = require("net"); let server = net.createServer(function (socket) { console.log(socket); let address = socket.address(); console.log("socket端口對象的地址信息為%j", address); // socket端口對象的地址信息為{"address":"127.0.0.1","family":"IPv4","port":2596} socket.setEncoding("utf8"); socket.on("data", function (data) { console.log(data); console.log("已接收到的字節(jié)數(shù)據(jù)長度", socket.bytesRead); /** * GET / HTTP/1.1 * User-Agent: curl/7.29.0 * Host: localhost:2596 * Accept: // 屬性值為"星號斜線星號",因?yàn)闀c注釋沖突,所以沒寫 * * * 已接收到的字節(jié)數(shù)據(jù)長度 78 * */ }); // 可以通過socket對象的pipe方法將客戶端發(fā)送的流數(shù)據(jù)寫到文件等其他目標(biāo)對象中 socket.pipe(file); socket.on("end", function () { console.log("客戶端連接已關(guān)閉"); // 當(dāng)客戶端連接關(guān)閉時,輸出"客戶端連接已關(guān)閉" }) }); server.getConnections(function (err, count) { console.log("當(dāng)前存在" + count + "個客戶端連接"); server.maxConnections = 2;// 設(shè)置最大連接為2 console.log("客戶端與服務(wù)器端已建立連接"); }); server.close(function () { console.log("TCP服務(wù)器被關(guān)閉"); }); server.on("error", function (e) { if (e.code === "EADDRINUSE") { console.log("該地址及端口被占用,請修正") } }); let address = server.address(); server.listen(2596, "localhost", 256, function () { console.log("服務(wù)器開始監(jiān)聽"); });
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/92891.html
摘要:創(chuàng)建客戶端對象與服務(wù)器的參數(shù)屬性一樣此時端口有下邊的幾個屬性連接另一端所使用的遠(yuǎn)程地址連接另一端所使用的端口號本地用于建立連接的地址本地用于建立連接的端口號端口對象可以被用來寫入向客戶端或服務(wù)器端發(fā)送的流數(shù)據(jù)當(dāng)流數(shù)據(jù)被寫入后將立即發(fā)送到客戶 1. 創(chuàng)建TCP客戶端 const net = require(net); let socket = new net.Socket([option...
摘要:然而,在處理流或文件流時,必須要處理二進(jìn)制數(shù)據(jù)。因此,在中,定義了一個類,該類用來創(chuàng)建一個專門存放二進(jìn)制數(shù)據(jù)的緩存區(qū)。因?yàn)樵谟?jì)算字符串的長度時,以位子作為一個單位,而在計(jì)算緩存區(qū)的長度時,以字節(jié)作為一個單位。 buffer對象 1. 什么是buffer 在客戶端Javascript腳本代碼中,對于二進(jìn)制數(shù)據(jù)沒有提供一個很好的支持。然而,在處理TCP流或文件流時,必須要處理二進(jìn)制數(shù)據(jù)...
摘要:下文如無特殊聲明將使用進(jìn)程同時表示進(jìn)程線程。收到數(shù)據(jù)后服務(wù)器程序進(jìn)行處理然后使用向客戶端發(fā)送響應(yīng)?,F(xiàn)在各種高并發(fā)異步的服務(wù)器程序都是基于實(shí)現(xiàn)的,比如。 并發(fā) IO 問題一直是服務(wù)器端編程中的技術(shù)難題,從最早的同步阻塞直接 Fork 進(jìn)程,到 Worker 進(jìn)程池/線程池,到現(xiàn)在的異步IO、協(xié)程。PHP 程序員因?yàn)橛袕?qiáng)大的 LAMP 框架,對這類底層方面的知識知之甚少,本文目的就是詳細(xì)介...
摘要:域套接字使用或指定請求方法的字符串。請求路徑包含非法字符時拋出異常。保持資源池周圍的套接字在未來被用于其它請求。默認(rèn)值為當(dāng)使用的時候,通過正在保持活動的套接字發(fā)送包的頻繁程度。 文章來源:小青年原創(chuàng)發(fā)布時間:2016-09-29關(guān)鍵詞:JavaScript,nodejs,http,url ,Query String,爬蟲轉(zhuǎn)載需標(biāo)注本文原始地址: http://zhaomenghuan....
閱讀 3419·2023-04-26 01:31
閱讀 1988·2023-04-25 22:08
閱讀 3733·2021-09-01 11:42
閱讀 2913·2019-08-30 12:58
閱讀 2278·2019-08-29 18:31
閱讀 2511·2019-08-29 17:18
閱讀 3141·2019-08-29 13:01
閱讀 2641·2019-08-28 18:22