首页 > Web开发 > 详细

简单了解 node net 模块

时间:2019-11-20 12:22:16      阅读:69      评论:0      收藏:0      [点我收藏+]

简单了解 node net 模块

文章简单记录了对net 模块的理解分析。

  • net模块
  • 简单使用
  • net.Server 对象
  • net.Socket 对象
  • 总结

 1.1 net模块

Node.js 的 Net模块用于创建基于流的 TCP 或 IPC 的服务器(net.createServer())与客户端(net.createConnection())。

Node.js 的 Net模块是基于TCP协议的socket网路编程模块。

主要的两个部分

  • net.Server
  • net.Socket

 1.2. 简单使用

先写个小例子:

TCP服务端:

let net = require(‘net‘)
let server = net.createServer({}, socket => {
  // socket 是一个双工流
  console.log(‘client connected‘)
  socket.on(‘data‘, data => {
    console.log(data.toString())
    socket.write(‘server: hello server‘)
  })
  // 服务器收到客户端发出的关闭请求时,会触发end事件
  socket.on(‘end‘, () => {
    console.log(‘client disconnected‘)
  })
  socket.on(‘close‘, () => {
    console.log(‘client closed‘)
  })
})
server.listen(8080, () => {
  console.log(‘server start‘);
})

TCP客户端:

let net = require(‘net‘)

// new net.Socket() 返回的是一个双工流
let client = new net.Socket()

client.connect(8080, ‘localhost‘, () => {
  console.log(‘connected server‘)
  client.write(‘client: hello server‘);
})
client.on(‘data‘, function (data) {
  console.log(data.toString())
});
setTimeout(()=>{
  client.end()
},5000)

上面流程调试代码画个简图:

技术分享图片

TCP服务是一connection 为单位进行服务的。

 1.3. net.Server 对象

createServer就是一个语法糖,帮助new生成server对象,

server 对象继承了EventEmitter对象 。

_handle属性值最终由c++部分的TCP、Pipe类创建的。

function Server(options, connectionListener) {
  if (!(this instanceof Server))
    return new Server(options, connectionListener);
  // 调用 EventEmitter 获得属性
  EventEmitter.call(this);
  // 订阅connection 事件
  this.on(‘connection‘, connectionListener);
  // 统计连接数量
  this._connections = 0;
  this[async_id_symbol] = -1;
// 会挂载TCP对象
this._handle = null; this._usingWorkers = false; this._workers = []; this._unref = false; this.allowHalfOpen = options.allowHalfOpen || false; this.pauseOnConnect = !!options.pauseOnConnect; }

每当有客户端连接时,就会调用callback函数onconnection函数,创建socket,然后在

self.emit(‘connection‘, socket)


所以server 对象更多的是对socket连接的管理。

function onconnection(err, clientHandle) {
  const handle = this;
  const self = handle[owner_symbol];
  // 超出最大链接数 不让客户端连接
  if (self.maxConnections && self._connections >= self.maxConnections) {
    clientHandle.close();
    return;
  }

  const socket = new Socket({
    handle: clientHandle,
    allowHalfOpen: self.allowHalfOpen,
    pauseOnCreate: self.pauseOnConnect,
    readable: true,
    writable: true
  });
  // 连接数增加
  self._connections++;
  socket.server = self;
  socket._server = self;

  DTRACE_NET_SERVER_CONNECTION(socket);
  // 发布 connection
  self.emit(‘connection‘, socket);
}

onconnection执行的目的是对应用程序构的连接造出一个socket的对象,并且基于此对象完成面向connection的数据流读取操作。

 1.4. net.Socket对象

socket(通过 socket=new Socket() ) 是个双工流源码截取如下:

技术分享图片

socket._handle上的对象是由C++中的Pipe、TCP实现,大概截取代码如下

//<------Socket函数----->
this._handle = createHandle(fd, false);


//<------createHandle函数----->
function createHandle(fd, is_server) {
  validateInt32(fd, ‘fd‘, 0);
  const type = guessHandleType(fd);
  if (type === ‘PIPE‘) {
    return new Pipe(
      is_server ? PipeConstants.SERVER : PipeConstants.SOCKET
    );
  }

  if (type === ‘TCP‘) {
    return new TCP(
      is_server ? TCPConstants.SERVER : TCPConstants.SOCKET
    );
  }

  throw new ERR_INVALID_FD_TYPE(type);
}

由c++部分的TCP、Pipe类创建由internalBinding(‘tcp_wrap‘)导出的TCP对象,如下:

技术分享图片

Node.js 的 Net模块其实是对 c++部分的TCP、Pipe类创建的socket 进行了抽象封装。

技术分享图片

所以socke实例有Writable,Readable,和TCP的相关功能函数。

 1.5. 总结

TCP服务是一connection 为单位进行服务的。

要理解net模块或者net模块的API 除了多看文档,还可以看看TCP协议,链接建立握手,慢启动拥塞控制,Nagle算法解决的问题等等。

文章简单记录了对net 模块的理解分析。例子用词比较粗糙,理解不准确之处,还请教正。

 

简单了解 node net 模块

原文:https://www.cnblogs.com/luoxiaoer/p/11894401.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!