nodejs实现套接字服务功能详解


Posted in NodeJs onJune 21, 2018

本文实例讲述了nodejs实现套接字服务功能。分享给大家供大家参考,具体如下:

一、什么是套接字

1. 套接字允许一个进程他通过一个IP地址和端口与另一个进程通信,当你实现对运行在同一台服务器上的两个不同进程的进程间通信或访问一个完全不同的服务器上运行的服务时,套接字很有用。node提供的net模块,允许你既创建套接字服务器又创建可以连接到套接字服务器的客户端。

2. 套接字位于HTTP层下面并提供服务器之间的点对点通信。套接字使用套接字地址来工作,这是IP地址和端口的组合。在套接字连接中,有两种类型的点:一类是服务器,它监听连接;一类是客户端,它打开一个到服务器的连接。服务器和客户端都需要一个唯一的IP地址和端口的组合。

3. 套接字是HTTP模块的底层结构,如果你不需要处理如get何post的web请求,只需要点对点的传输数据,那么使用套接字就可以就能为你提供一个轻量级的解决方案和更多的控制。

二、net.Socket对象

1. Socket对象同时在套接字服务器和客户端套接字上创建,并允许数据在它们之间来回写入和读取。在套接字客户端,当你调用net.connect()net.createConnection()时,Socket对象在内部创建,这个对象是为了表示到服务器的套接字连接。使用Socket对象来监控连接,将数据发送到服务器并处理来自服务器的响应。在套接字服务器上,当客户端连接到服务器时,Socket对象被创建,并被传递到连接事件处理程序,这个对象是为了表示对客户端的套接字连接。      在NodeJS中有三种socket:TCPUDPUnix域套接字,主要介绍NodeJS中TCP的基本编程知识。

2. 创建一个Socket对象,可以使用以下方法:

//第一种方法,通过一个options参数
var SocketClient = net.connect(options, [connectionListener]);
var SocketClient = net.createConnection(options, [connectionListener]);
//第二种方法,通过接受port和host值作为直接的参数
var SocketClient = net.connect(port, [host], [connectionListener]);
var SocketClient = net.createConnection(port, [host], [connectionListener]);
//第三种方法,通过接受指定文件系统位置的path参数,这个位置是一个Unix套接字在创建Socket对象时使用的。
var SocketClient = net.connect(path, [connectionListener]);
var SocketClient = net.createConnection(path, [connectionListener]);

无论你使用哪种,都将返回一个Socket对象,唯一的区别在于接受的第一个参数,而最后一个参数都是当连接对服务器打开时执行的回调函数。而无论你使用net.connect还是net.createConncetion,它们的工作方式是完全相同的。

那么至于第一个参数,指定的选项为:

port:客户端应连接到的端口。此选项是必需的。
host:客户端应该连接到的服务器的域名或IP地址。默认为localhost
localAddress:客户端应该绑定的用于网络连接的本地IP地址。
allowHalfOpen:一个布尔值,如果为true,则表示当套接字的另一端发送一个FIN数据包时,该套接字将不会自动发送一个FIN数据包,从而使Duplex流的一半保持开放。默认为false

3. 一旦Socket对象被创建,它就提供了在连接到服务器的生命周期中发出的几个事件,如下:

connect:成功建立与服务器的连接时发出。回调函数不接受任何参数
data:在套接字上收到数据时发出。如果没有数据时间处理程序被连接,那么数据可能会丢失。回调函数必须接受一个buffer对象作为参数,它包含从套接字读取的数据的块。
end:当服务器通过发送一个FIN终止连接时发出。回调函数不接受任何参数
timeout:由于不活动,因此到服务器的连接超时时发出。
drain:当写缓冲区变为空时发出。你可以使用此事件截回被写入套接字中的数据流。回调函数不接受任何参数
error:在套接字连接上发生错误时发出。回调函数应该接受错误的唯一参数。
close:套接字已完全关闭时发出,它可能是由一个end()方法关闭的,或者因为发生错误而关闭。回调函数不接受任何参数

4. Socket对象还提供了可以访问以获得该对象的信息的几个属性:

bufferSize   当前已缓冲并等待写入套接字的流中的字节数
remoteAddress   套接字连接到的远程服务器的IP地址
remotePort    套接字连接到的远程服务器的端口
localAddress   远程客户端用于套接字连接的本地IP地址
localPort     远程客户端用于套接字连接的本地端口
byteRead     由套接字读取的字节数
byteWritten    由套接字写入的字节数

三、net.Server对象

可以使用net.Server对象创建一个TCP套接字服务器,并监听对它的连接,你将能够读取和写入数据。

要创建一个服务器独享,使用net.createServer()方法:

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

其中,options是一个对象,指定创建套接字Server对象时要使用的选项,如allowHalfOpen,可以使一半的Duplex流保持开放,默认为false。connectLlistenerconnection事件的回调函数,它在接收到连接时被执行。

举例:

var net = require('net');
var HOST = '127.0.0.1';
var PORT = 6969;
// 创建一个TCP服务器实例,调用listen函数开始监听指定端口
// 传入net.createServer()的回调函数将作为”connection“事件的处理函数
// 在每一个“connection”事件中,该回调函数接收到的socket对象是唯一的
net.createServer(function(sock) {
  // 我们获得一个连接 - 该连接自动关联一个socket对象
  console.log('CONNECTED: ' + sock.remoteAddress + ':' + sock.remotePort);
  // 为这个socket实例添加一个"data"事件处理函数
  sock.on('data', function(data) {
    console.log('DATA ' + sock.remoteAddress + ': ' + data);
    // 回发该数据,客户端将收到来自服务端的数据
    sock.write('You said "' + data + '"');
  });
  // 为这个socket实例添加一个"close"事件处理函数
  sock.on('close', function(data) {
    console.log('CLOSED: ' +
      sock.remoteAddress + ' ' + sock.remotePort);
  });
}).listen(PORT, HOST);
console.log('Server listening on ' + HOST +':'+ PORT);

服务端也可以用稍不同的方式接受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);
  // 其它内容与前例相同
});

上述两个例子只是写法不同,并无本质区别。

创建TCP客户端

现在让我们创建一个TCP客户端连接到刚创建的服务器上,该客户端向服务器发送一串消息,并在得到服务器的反馈后关闭连接。下面的代码描述了这一过程。

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);
  // 建立连接后立即向服务器发送数据,服务器将收到这些数据
  client.write('I am Chuck Norris!');
});
// 为客户端添加“data”事件处理函数
// data是服务器发回的数据
client.on('data', function(data) {
  console.log('DATA: ' + data);
  // 完全关闭连接
  client.destroy();
});
// 为客户端添加“close”事件处理函数
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实现套接字服务功能详解

希望本文所述对大家nodejs程序设计有所帮助。

NodeJs 相关文章推荐
基于NodeJS的前后端分离的思考与实践(二)模版探索
Sep 26 NodeJs
深入浅析NodeJs并发异步的回调处理
Dec 21 NodeJs
nodejs实现bigpipe异步加载页面方案
Jan 26 NodeJs
Nodejs中 npm常用命令详解
Jul 04 NodeJs
详解nodejs 文本操作模块-fs模块(五)
Dec 23 NodeJs
Nodejs中使用captchapng模块生成图片验证码
May 18 NodeJs
nodejs集成sqlite使用示例
Jun 05 NodeJs
深入浅析Nodejs的Http模块
Jun 20 NodeJs
NodeJS实现图片上传代码(Express)
Jun 30 NodeJs
nodejs动态创建二维码的方法
Aug 12 NodeJs
Windows下使用Nodejs运行js的方法
Sep 02 NodeJs
nodejs判断文件、文件夹是否存在及删除的方法
Nov 10 NodeJs
详解Nodejs mongoose
Jun 10 #NodeJs
详解NodeJs开发微信公众号
May 25 #NodeJs
nodejs express配置自签名https服务器的方法
May 22 #NodeJs
通过nodejs 服务器读取HTML文件渲染到页面的方法
May 17 #NodeJs
解决nodejs的npm命令无反应的问题
May 17 #NodeJs
Mac下通过brew安装指定版本的nodejs教程
May 17 #NodeJs
对mac下nodejs 更新到最新版本的最新方法(推荐)
May 17 #NodeJs
You might like
PHP树的代码,可以嵌套任意层
2006/10/09 PHP
PHP版网站缓存加快打开速度的方法分享
2012/06/03 PHP
PHP代码优化技巧小结
2015/09/29 PHP
PHP关于foreach复制知识点总结
2019/01/28 PHP
CI框架教程之优化验证码机制详解【验证码辅助函数】
2019/04/16 PHP
PHP命名空间与自动加载机制的基础介绍
2019/08/25 PHP
php设计模式之中介者模式分析【星际争霸游戏案例】
2020/03/23 PHP
JavaScript Event学习第三章 早期的事件处理程序
2010/02/07 Javascript
EXT窗口Window及对话框MessageBox
2011/01/27 Javascript
一个JQuery操作Table的代码分享
2012/03/30 Javascript
基于jQuery实现多层次的手风琴效果附源码
2015/09/21 Javascript
解析ajaxFileUpload 异步上传文件简单使用
2016/12/30 Javascript
在 Angular 中使用Chart.js 和 ng2-charts的示例代码
2017/08/17 Javascript
jQuery实现经典的网页3D轮播图封装功能【附源码下载】
2019/02/15 jQuery
解决vue项目中页面调用数据 在数据加载完毕之前出现undefined问题
2019/11/14 Javascript
JS实现滑动导航效果
2020/01/14 Javascript
js+html+css实现手动轮播和自动轮播
2020/12/30 Javascript
Python算法之栈(stack)的实现
2014/08/18 Python
Python2.7简单连接与操作MySQL的方法
2016/04/27 Python
快速实现基于Python的微信聊天机器人示例代码
2017/03/03 Python
Python实现破解猜数游戏算法示例
2017/09/25 Python
TensorFlow实现Softmax回归模型
2018/03/09 Python
python与caffe改变通道顺序的方法
2018/08/04 Python
Anaconda 查看、创建、管理和使用python环境的方法
2019/12/03 Python
Python imutils 填充图片周边为黑色的实现
2020/01/19 Python
实例教程 纯CSS3打造非常炫的加载动画效果
2014/11/05 HTML / CSS
结合 CSS3 transition transform 实现简单的跑马灯效果的示例
2018/02/07 HTML / CSS
基督教卡片、励志礼品、家居装饰等:DaySpring
2018/10/12 全球购物
Perfume’s Club意大利官网:欧洲美妆电商
2019/05/03 全球购物
意大利顶级奢侈品电商:LUISAVIAROMA(支持中文)
2020/05/26 全球购物
银行类自荐信
2014/02/04 职场文书
《满井游记》教学反思
2014/02/26 职场文书
咖啡店创业计划书
2014/08/15 职场文书
大学毕业生管理学求职信
2014/09/01 职场文书
Python 中的单分派泛函数你真的了解吗
2021/06/22 Python
总结Python变量的相关知识
2021/06/28 Python