本文实例讲述了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实现套接字服务功能详解的更多相关文章

  1. 配置iOS VoIP应用程序以在睡眠/后台模式下运行

    我正在开发基于VoIP的iOS(7.1)应用程序.它的底层套接字编程是用C而不是客观C编写的.应用程序在前台运行良好,但在进入睡眠/后台模式时,它无法从服务器接收任何通信.根据apple文档,我们必须为VoIP使用配置一个appsocket.我无法弄清楚如何配置C套接字.目的是在睡眠模式下运行应用程序,直到它被杀死.从SO中尝试了几个链接甚至几个链接,但由于我是新手,我希望这个配置有一步一步的过程.[注意:在某个地方我发现了CoreFoudation框架,我是否需要使用它?

  2. 我应该使用哪个高级API来管理iOS上的UDP套接字?

    在“NetworkProgrammingTopicsConceptualGuide”的“UsingSocketsandStreams”一章中,Apple说:Note:POSIXnetworkingdoesnotactivatethecellularradiooniOS.Forthisreason,thePOSIXnetworkingAPIisgenerallydiscouragediniOS.同样

  3. iOS:使用CFStreamCreatePairWithSocketToHost的套接字网络基础

    >每次要发送新数据对象时,是否设置了新套接字?>我是否必须重置outputStream并发送更多数据.码大部分代码来自CocoaStreamsDocumentation:响应:请注意,在发送数据后,outputStream流将关闭.我尝试在[selfsendString:@“AnotherTest”]之前重新启动outputStream.我也试过了idz的回答.根据文档,我相信len:0的发送缓冲区是我的问题.IfthedelegatereceivesanNsstreamEventHasspaceAvai

  4. ios – AFNetworking / NSURLConnection接收NSPOSIXErrorDomain代码= 9“操作无法完成.坏文件描述符“

    有人在他们的AFNetworking操作中遇到这个错误吗?此外,如果我真的想要,如何故意关闭这个文件描述符?

  5. iOS:无法完成套接字错误操作断管

    我每隔一段时间就会从iOS应用程序向套接字服务器发送一些数据.它正确地发送数据.我看到一个奇怪的问题,如果iOS设备屏幕在从iOS应用程序发送数据时关闭,然后如果我在设备上屏幕,然后我收到以下错误,应用程序已经与套接字断开连接或有时它会崩溃应用程序:当设备屏幕关闭时,我的iOS应用程序停止向套接字发送数据.然后再打开屏幕,插座连接断开/断开管道错误.怎么解决?

  6. android和ios有多少端口号?

    我试过谷歌,但甚至看不到关于这个的帖子.当我想在android中创建socket时,我们在PC中创建套接字的规则是否同样适用于android?程序在一个端口侦听并等待创建套接字?解决方法你有一个ServerSocket和一个Socket.调用Socketclient=ss.accept()等到客户端挂钩.如果您不确定哪个端口是空闲的,只需使用ss=newServerSocket().这将自动分配一个空闲端口.另外,请确保不要在主线程上执行此操作,并在清单中声明相应的权限.

  7. Android从服务器套接字侦听消息

    解决方法您可以在服务中创建一个线程来监听服务器.第二个线程用于发送命令.然后,对于您的服务,您应该创建一个带有处理程序的主线程.此处理程序将处理来自这两个线程的消息.

  8. 在android上的活动之间保持套接字连接

    我正在android3.1上开发一个应用程序,我有一个ActivityA,它有一个从aSyncTask扩展的子类,这个子类创建一个套接字并连接到服务器.我所有的沟通都很好.我收到消息并向服务器发送命令,但是当我得到一个特定命令时,我必须开始第二个活动(活动B),但我不能丢失我的套接字并与服务器建立通信,而且我必须仍然能够从活动B接收和发送命令到服务器.我怎样才能做到这一点??

  9. Android – 本机套接字在首次尝试时不会删除3G睡眠模式

    我有一个非常讨厌的问题.发生的事情是我有一个使用本机套接字通过TCP发送数据的应用程序.当我第一次启动我的应用程序并通过套接字发送数据时,没有任何东西通过.但是,如果我然后退出该过程并重新启动然后再次发送,则可以正常工作.如果我在睡眠模式后第一次启动我的应用程序之前打开浏览器或其他东西也一样.在调用本机代码之前,如何强制“3G”退出睡眠模式?

  10. android – 如何在主线程上运行服务?

    我正在尝试启动服务,然后打开套接字与服务器连接.在按钮上单击我创建新线程然后启动服务.然后在服务上,我尝试打开套接字并与服务器连接但是当我打电话给我时,我有错误我认为问题是服务在主线程上,但是我找不到如何在新的(独立)线程上启动服务以保持连接活动?

随机推荐

  1. Error: Cannot find module ‘node:util‘问题解决

    控制台 安装 Vue-Cli 最后一步出现 Error: Cannot find module 'node:util' 问题解决方案1.问题C:\Windows\System32>cnpm install -g @vue/cli@4.0.3internal/modules/cjs/loader.js:638 throw err; &nbs

  2. yarn的安装和使用(全网最详细)

    一、yarn的简介:Yarn是facebook发布的一款取代npm的包管理工具。二、yarn的特点:速度超快。Yarn 缓存了每个下载过的包,所以再次使用时无需重复下载。 同时利用并行下载以最大化资源利用率,因此安装速度更快。超级安全。在执行代码之前,Yarn 会通过算法校验每个安装包的完整性。超级可靠。使用详细、简洁的锁文件格式和明确的安装算法,Yarn 能够保证在不同系统上无差异的工作。三、y

  3. 前端环境 本机可切换node多版本 问题源头是node使用的高版本

    前言投降投降 重头再来 重装环境 也就分分钟的事 偏要折腾 这下好了1天了 还没折腾出来问题的源头是node 使用的高版本 方案那就用 本机可切换多版本最终问题是因为nodejs的版本太高,导致的node-sass不兼容问题,我的node是v16.14.0的版本,项目中用了"node-sass": "^4.7.2"版本,无法匹配当前的node版本根据文章的提

  4. nodejs模块学习之connect解析

    这篇文章主要介绍了nodejs模块学习之connect解析,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  5. nodejs npm package.json中文文档

    这篇文章主要介绍了nodejs npm package.json中文文档,本文档中描述的很多行为都受npm-config(7)的影响,需要的朋友可以参考下

  6. 详解koa2学习中使用 async 、await、promise解决异步的问题

    这篇文章主要介绍了详解koa2学习中使用 async 、await、promise解决异步的问题,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

  7. Node.js编写爬虫的基本思路及抓取百度图片的实例分享

    这篇文章主要介绍了Node.js编写爬虫的基本思路及抓取百度图片的实例分享,其中作者提到了需要特别注意GBK转码的转码问题,需要的朋友可以参考下

  8. CentOS 8.2服务器上安装最新版Node.js的方法

    这篇文章主要介绍了CentOS 8.2服务器上安装最新版Node.js的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  9. node.js三个步骤实现一个服务器及Express包使用

    这篇文章主要介绍了node.js三个步骤实现一个服务器及Express包使用,文章通过新建一个文件展开全文内容,具有一定的参考价值,需要的小伙伴可以参考一下

  10. node下使用UglifyJS压缩合并JS文件的方法

    下面小编就为大家分享一篇node下使用UglifyJS压缩合并JS文件的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

返回
顶部