欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

nodejs實現(xiàn)套接字服務(wù)功能詳解

 更新時間:2018年06月21日 15:14:43   作者:LittleMoon  
這篇文章主要介紹了nodejs實現(xiàn)套接字服務(wù)功能,簡單描述了套接字的概念、功能,并結(jié)合實例形式分析了nodejs使用socket對象創(chuàng)建及使用套接字進(jìn)行數(shù)據(jù)傳輸相關(guān)操作技巧與注意事項,需要的朋友可以參考下

本文實例講述了nodejs實現(xiàn)套接字服務(wù)功能。分享給大家供大家參考,具體如下:

一、什么是套接字

1. 套接字允許一個進(jìn)程他通過一個IP地址和端口與另一個進(jìn)程通信,當(dāng)你實現(xiàn)對運(yùn)行在同一臺服務(wù)器上的兩個不同進(jìn)程的進(jìn)程間通信或訪問一個完全不同的服務(wù)器上運(yùn)行的服務(wù)時,套接字很有用。node提供的net模塊,允許你既創(chuàng)建套接字服務(wù)器又創(chuàng)建可以連接到套接字服務(wù)器的客戶端。

2. 套接字位于HTTP層下面并提供服務(wù)器之間的點(diǎn)對點(diǎn)通信。套接字使用套接字地址來工作,這是IP地址和端口的組合。在套接字連接中,有兩種類型的點(diǎn):一類是服務(wù)器,它監(jiān)聽連接;一類是客戶端,它打開一個到服務(wù)器的連接。服務(wù)器和客戶端都需要一個唯一的IP地址和端口的組合。

3. 套接字是HTTP模塊的底層結(jié)構(gòu),如果你不需要處理如get何post的web請求,只需要點(diǎn)對點(diǎn)的傳輸數(shù)據(jù),那么使用套接字就可以就能為你提供一個輕量級的解決方案和更多的控制。

二、net.Socket對象

1. Socket對象同時在套接字服務(wù)器和客戶端套接字上創(chuàng)建,并允許數(shù)據(jù)在它們之間來回寫入和讀取。在套接字客戶端,當(dāng)你調(diào)用net.connect()net.createConnection()時,Socket對象在內(nèi)部創(chuàng)建,這個對象是為了表示到服務(wù)器的套接字連接。使用Socket對象來監(jiān)控連接,將數(shù)據(jù)發(fā)送到服務(wù)器并處理來自服務(wù)器的響應(yīng)。在套接字服務(wù)器上,當(dāng)客戶端連接到服務(wù)器時,Socket對象被創(chuàng)建,并被傳遞到連接事件處理程序,這個對象是為了表示對客戶端的套接字連接。      在NodeJS中有三種socket:TCPUDP,Unix域套接字,主要介紹NodeJS中TCP的基本編程知識。

2. 創(chuàng)建一個Socket對象,可以使用以下方法:

//第一種方法,通過一個options參數(shù)
var SocketClient = net.connect(options, [connectionListener]);
var SocketClient = net.createConnection(options, [connectionListener]);
//第二種方法,通過接受port和host值作為直接的參數(shù)
var SocketClient = net.connect(port, [host], [connectionListener]);
var SocketClient = net.createConnection(port, [host], [connectionListener]);
//第三種方法,通過接受指定文件系統(tǒng)位置的path參數(shù),這個位置是一個Unix套接字在創(chuàng)建Socket對象時使用的。
var SocketClient = net.connect(path, [connectionListener]);
var SocketClient = net.createConnection(path, [connectionListener]);

無論你使用哪種,都將返回一個Socket對象,唯一的區(qū)別在于接受的第一個參數(shù),而最后一個參數(shù)都是當(dāng)連接對服務(wù)器打開時執(zhí)行的回調(diào)函數(shù)。而無論你使用net.connect還是net.createConncetion,它們的工作方式是完全相同的。

那么至于第一個參數(shù),指定的選項為:

port:客戶端應(yīng)連接到的端口。此選項是必需的。
host:客戶端應(yīng)該連接到的服務(wù)器的域名或IP地址。默認(rèn)為localhost
localAddress:客戶端應(yīng)該綁定的用于網(wǎng)絡(luò)連接的本地IP地址。
allowHalfOpen:一個布爾值,如果為true,則表示當(dāng)套接字的另一端發(fā)送一個FIN數(shù)據(jù)包時,該套接字將不會自動發(fā)送一個FIN數(shù)據(jù)包,從而使Duplex流的一半保持開放。默認(rèn)為false

3. 一旦Socket對象被創(chuàng)建,它就提供了在連接到服務(wù)器的生命周期中發(fā)出的幾個事件,如下:

connect:成功建立與服務(wù)器的連接時發(fā)出?;卣{(diào)函數(shù)不接受任何參數(shù)
data:在套接字上收到數(shù)據(jù)時發(fā)出。如果沒有數(shù)據(jù)時間處理程序被連接,那么數(shù)據(jù)可能會丟失?;卣{(diào)函數(shù)必須接受一個buffer對象作為參數(shù),它包含從套接字讀取的數(shù)據(jù)的塊。
end:當(dāng)服務(wù)器通過發(fā)送一個FIN終止連接時發(fā)出?;卣{(diào)函數(shù)不接受任何參數(shù)
timeout:由于不活動,因此到服務(wù)器的連接超時時發(fā)出。
drain:當(dāng)寫緩沖區(qū)變?yōu)榭諘r發(fā)出。你可以使用此事件截回被寫入套接字中的數(shù)據(jù)流?;卣{(diào)函數(shù)不接受任何參數(shù)
error:在套接字連接上發(fā)生錯誤時發(fā)出?;卣{(diào)函數(shù)應(yīng)該接受錯誤的唯一參數(shù)。
close:套接字已完全關(guān)閉時發(fā)出,它可能是由一個end()方法關(guān)閉的,或者因為發(fā)生錯誤而關(guān)閉。回調(diào)函數(shù)不接受任何參數(shù)

4. Socket對象還提供了可以訪問以獲得該對象的信息的幾個屬性:

bufferSize   當(dāng)前已緩沖并等待寫入套接字的流中的字節(jié)數(shù)
remoteAddress   套接字連接到的遠(yuǎn)程服務(wù)器的IP地址
remotePort    套接字連接到的遠(yuǎn)程服務(wù)器的端口
localAddress   遠(yuǎn)程客戶端用于套接字連接的本地IP地址
localPort     遠(yuǎn)程客戶端用于套接字連接的本地端口
byteRead     由套接字讀取的字節(jié)數(shù)
byteWritten    由套接字寫入的字節(jié)數(shù)

三、net.Server對象

可以使用net.Server對象創(chuàng)建一個TCP套接字服務(wù)器,并監(jiān)聽對它的連接,你將能夠讀取和寫入數(shù)據(jù)。

要創(chuàng)建一個服務(wù)器獨(dú)享,使用net.createServer()方法:

net.createServer([options],[connectListener])

其中,options是一個對象,指定創(chuàng)建套接字Server對象時要使用的選項,如allowHalfOpen,可以使一半的Duplex流保持開放,默認(rèn)為false。connectLlistenerconnection事件的回調(diào)函數(shù),它在接收到連接時被執(zhí)行。

舉例:

var net = require('net');
var HOST = '127.0.0.1';
var PORT = 6969;
// 創(chuàng)建一個TCP服務(wù)器實例,調(diào)用listen函數(shù)開始監(jiān)聽指定端口
// 傳入net.createServer()的回調(diào)函數(shù)將作為”connection“事件的處理函數(shù)
// 在每一個“connection”事件中,該回調(diào)函數(shù)接收到的socket對象是唯一的
net.createServer(function(sock) {
  // 我們獲得一個連接 - 該連接自動關(guān)聯(lián)一個socket對象
  console.log('CONNECTED: ' + sock.remoteAddress + ':' + sock.remotePort);
  // 為這個socket實例添加一個"data"事件處理函數(shù)
  sock.on('data', function(data) {
    console.log('DATA ' + sock.remoteAddress + ': ' + data);
    // 回發(fā)該數(shù)據(jù),客戶端將收到來自服務(wù)端的數(shù)據(jù)
    sock.write('You said "' + data + '"');
  });
  // 為這個socket實例添加一個"close"事件處理函數(shù)
  sock.on('close', function(data) {
    console.log('CLOSED: ' +
      sock.remoteAddress + ' ' + sock.remotePort);
  });
}).listen(PORT, HOST);
console.log('Server listening on ' + HOST +':'+ PORT);

服務(wù)端也可以用稍不同的方式接受TCP連接,即顯式處理"connection"事件:

var server = net.createServer();
server.listen(PORT, HOST);
console.log('Server listening on ' +
  server.address().address + ':' + server.address().port);
server.on('connection', function(sock) {
  console.log('CONNECTED: ' +
     sock.remoteAddress +':'+ sock.remotePort);
  // 其它內(nèi)容與前例相同
});

上述兩個例子只是寫法不同,并無本質(zhì)區(qū)別。

創(chuàng)建TCP客戶端

現(xiàn)在讓我們創(chuàng)建一個TCP客戶端連接到剛創(chuàng)建的服務(wù)器上,該客戶端向服務(wù)器發(fā)送一串消息,并在得到服務(wù)器的反饋后關(guān)閉連接。下面的代碼描述了這一過程。

var net = require('net');
var HOST = '127.0.0.1';
var PORT = 6969;
var client = new net.Socket();
client.connect(PORT, HOST, function() {
  console.log('CONNECTED TO: ' + HOST + ':' + PORT);
  // 建立連接后立即向服務(wù)器發(fā)送數(shù)據(jù),服務(wù)器將收到這些數(shù)據(jù)
  client.write('I am Chuck Norris!');
});
// 為客戶端添加“data”事件處理函數(shù)
// data是服務(wù)器發(fā)回的數(shù)據(jù)
client.on('data', function(data) {
  console.log('DATA: ' + data);
  // 完全關(guān)閉連接
  client.destroy();
});
// 為客戶端添加“close”事件處理函數(shù)
client.on('close', function() {
  console.log('Connection closed');
});

再舉個例子:

var net=require('net');
function getConnection(connName){
  var client=net.connect({port:8017,host:'127.0.0.1'},function(){
    console.log(connName+' connected: ');
    console.log(' local=%s:%s',this.localAddress,this.localPort);
    console.log( ' remote=%s:%s',this.remoteAddress,this.remotePort);
    this.setTimeout(500);
    this.setEncoding('utf8');
    this.on('data',function(data){
      console.log(connName+' From Server: '+data.toString());
      this.end();
    });
    this.on('end',function(){
      console.log(connName+' Client disnected');
    });
    this.on('error',function(err){
      console.log('Socket Error: ',JSON.stringify(err));
    });
    this.on('timeout',function(){
      console.log('Socket Time Out');
    });
    this.on('close',function(){
      console.log('Socket Closed');
    });
  });
  return client;
}
function writeData(socket,data){
  var success=!socket.write(data);
  if(!success){
    (function (socket,data){
      socket.once('drain',function(){
        writeData(socket,data);
      });
    })(socket,data);
  }
}
var example1=getConnection('example1');
var example2=getConnection('example2');
writeData(example1,'This is example1');
writeData(example2,'This is example2');
var server=net.createServer(function(client){
  console.log('Client connection: ');
  console.log(' local=%s:%s',client.localAddress,client.localPort);
  console.log( ' remote=%s:%s',client.remoteAddress,client.remotePort);
  client.setTimeout(500);
  client.setEncoding('utf8');
  client.on('data',function(data){
    console.log('Received data from client on port %d:%s',client.remotePort,data.toString());
    console.log(' Bytes received:'+data.toString());
    writeData(client,'Sending: '+data.toString());
    console.log(' Bytes sent: '+client.bytesWritten)
  });
  client.on('end',function(){
    console.log('Client disconnected');
    server.getConnections(function(err,count){
      console.log('Remaining Connections: '+count);
    });
  });
  client.on('error',function(err){
    console.log('Socket Error: '+JSON.stringify(err));
  });
  client.on('timeout',function(){
    console.log('Socket Time Out');
  });
});
server.listen(8017,function(){
  console.log('Server listening: '+JSON.stringify(server.address()));
  server.on('close',function(){
    console.log('Server Terminated');
  });
  server.on('error',function(err){
    console.log('Server Error: ',JSON.stringify(err));
  });
});

希望本文所述對大家nodejs程序設(shè)計有所幫助。

相關(guān)文章

  • Node.js與MySQL交互操作及其注意事項

    Node.js與MySQL交互操作及其注意事項

    這篇文章給大家主要介紹了Node.js與MySQL交互操作及其注意事項,非常的詳細(xì),有相同需求的小伙伴可以參考下
    2016-10-10
  • nvm管理node無法正常切換node版本問題的解決方法

    nvm管理node無法正常切換node版本問題的解決方法

    相信一定會有存在一些小伙伴 明明都已經(jīng)按著操作卸載node 和安裝nvm 了但是 依舊無法正常通過nvm管理node,本文將給大家介紹nvm管理node無法正常切換node版本問題的解決方法,需要的朋友可以參考下
    2024-01-01
  • Nodejs實現(xiàn)的操作MongoDB數(shù)據(jù)庫功能完整示例

    Nodejs實現(xiàn)的操作MongoDB數(shù)據(jù)庫功能完整示例

    這篇文章主要介紹了Nodejs實現(xiàn)的操作MongoDB數(shù)據(jù)庫功能,結(jié)合完整實例形式分析了nodejs針對MongoDB數(shù)據(jù)庫的連接及增刪改查基本操作技巧,需要的朋友可以參考下
    2019-02-02
  • 利用C/C++編寫node.js原生模塊的方法教程

    利用C/C++編寫node.js原生模塊的方法教程

    這篇文章主要給大家介紹了關(guān)于利用C/C++編寫node.js原生模塊的相關(guān)資料,文中將實現(xiàn)的步驟一步步的介紹的非常詳細(xì),對大家具有一定的參考學(xué)習(xí)價值,需要的朋友們下面跟著小編來一起看看吧。
    2017-07-07
  • 在Debian(Raspberry Pi)樹莓派上安裝NodeJS的教程詳解

    在Debian(Raspberry Pi)樹莓派上安裝NodeJS的教程詳解

    在樹莓派上運(yùn)行NodeJS并不需要特別的配置,你只需要確??梢杂胦penssh遠(yuǎn)程連接到你的樹莓派就ok了,關(guān)于在Debian(Raspberry Pi)樹莓派上安裝NodeJS的方法,大家可以通過本文了解下
    2017-09-09
  • nodejs文件操作模塊FS(File System)常用函數(shù)簡明總結(jié)

    nodejs文件操作模塊FS(File System)常用函數(shù)簡明總結(jié)

    這篇文章主要介紹了nodejs文件操作模塊FS(File System)常用函數(shù)簡明總結(jié),對FS模塊的大部份異步函數(shù)做了介紹,而且用中文注釋,這下用起來方便了,需要的朋友可以參考下
    2014-06-06
  • Node.js刷新session過期時間的實現(xiàn)方法推薦

    Node.js刷新session過期時間的實現(xiàn)方法推薦

    下面小編就為大家?guī)硪黄狽ode.js刷新session過期時間的實現(xiàn)方法推薦。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-05-05
  • 詳解使用nvm管理多版本node的方法

    詳解使用nvm管理多版本node的方法

    本篇文章主要介紹了詳解使用 nvm 管理多版本 node的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • 深入解析nodejs HTTP服務(wù)

    深入解析nodejs HTTP服務(wù)

    本篇文章主要介紹了深入解析nodejs HTTP服務(wù),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-07-07
  • 使用nodeAPI時遇到過異步問題解決

    使用nodeAPI時遇到過異步問題解決

    這篇文章主要為大家介紹了使用nodeAPI時遇到過異步問題解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01

最新評論