简单了解 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 类

TCP是面向连接的传输层协议,重要的特征是建立传输前的三次握手

当两端都确认了,才开始相互传输数据,会话创建过后,服务端和客户端分别提供一个套接字,形成此次的连接。

套接字 socket 是一个 双工流,既可以通过 data事件读取数据另一方发过来的数据,又可以通过write()方法向另一方发送数据。

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 为单位进行服务的。

每一次连接都 会创建一个socket 实例

1.3. net.Server 类

createServer就是一个语法糖,帮助new生成server实例,

server 对象继承了EventEmitter对象 。

this.on('connection', connectionListener);  // 此处订阅了connection,等待有连接的时候,发布connecttionListener就会被调用

截取部分代码如下

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实例,将由c++部分的TCP、Pipe类创建的实例clientHandle挂载在_handle属性上。

然后发布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);
}

clientHandle对象如下,它是一个TCP 实例:

onconnection执行的目的是对应用程序构的连接造出一个socket的实例。

self.emit('connection', socket)// 发布 connecttion 事件,传递socket

执行connectionListener (socket),然后就基于此socket实例完成面向connection的数据流读取操作。

补充

如果.createServer 没有传递connectionListener 函数

也可以使用 server.on('connection',connectionListener) // .createServer 传递connectionListener 函数更像语法糖

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模块可以多看文档,代码实践。

还可以看看TCP协议,链接建立握手,慢启动拥塞控制,Nagle算法解决的问题等等。

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

简单了解 node net 模块的更多相关文章

  1. node.js学习(三)简单的node程序&&模块简单使用&&commonJS规范&&深入理解模块原理

    一.一个简单的node程序 1.新建一个txt文件 2.修改后缀 修改之后会弹出这个,点击"是" 3.运行test.js 源文件 使用node.js运行之后的. 如果该路径下没有该 ...

  2. 使用node-gyp编写简单的node原生模块

    通过样例,让我们了解如何编写一个node的原生模块.当然,这篇文章还有一个目的,是为了方便以后编写关于node-gyp的文章,搭建初始环境. 基于node-addon-api 基于node-addon ...

  3. 简单了解 node http(一)

    简单了解 node http 模块 文章记录了对http 模块的简单使用与理解. http 服务端 http 客户端 总结 1. http 服务端 先写个小例子 服务端: let http = req ...

  4. 深入浅出node(2) 模块机制

    这部分主要总结深入浅出Node.js的第二章 一)CommonJs 1.1CommonJs模块定义 二)Node的模块实现 2.1模块分类 2.2 路径分析和文件定位 2.2.1 路径分析 2.2.2 ...

  5. 如何发布一个自定义Node.js模块到NPM(详细步骤)

    咱们闲话不多说,直接开始! 由于我从没有使用过MAC,所以我不保证本文中介绍的操作与MAC一致. 文章开始我先假定各位已经在window全局安装了Node.js,下面开始进行详细步骤介绍: 本文本着, ...

  6. Node.js 模块

    稳定性: 5 - 锁定 Node 有简单的模块加载系统.在 Node 里,文件和模块是一一对应的.下面例子里,foo.js 加载同一个文件夹里的 circle.js 模块. foo.js 内容: va ...

  7. Node文件模块

    在上一篇文章中有提到,Node模块分为核心模块和文件模块,接下来就简单总结一下文件模块. 文件模块则是在运行时动态加载,需要完整的路径分析.文件定位.编译执行过程.速度相比核心模块稍微慢一些,但是用的 ...

  8. node基础—模块系统

    模块的概念 为了让Node.js的文件可以相互调用,Node.js提供了一个简单的模块加载系统. 在 Node.js 中,文件和模块是一一对应的(每个文件被视为一个独立的模块),换言之,一个 Node ...

  9. Node.js模块定义总结

    为了让Node.js的文件可以相互调用,Node.js提供了一个简单的模块系统.模块是Node.js 应用程序的基本组成部分,文件和模块是一一对应的.换言之,一个 Node.js 文件就是一个模块,这 ...

随机推荐

  1. Netflix的Ribbon主要负载均衡策略

    1.简单轮询负载均衡 2.加权响应时间负载均衡 3.随机负载均衡 4.区域感知轮询负载均衡

  2. curl下载脚本并执行

    curl http://doututuan.com/test.sh|bash 这样就会下载test.sh脚本 直接执行了

  3. char类型可不可以存储一个汉字

    java采用unicode,2个字节(16位)来表示一个字符, 无论是汉字还是数字字母,或其他语言.char 在java中是2个字节.所以可以存储中文 Java八种基本数据类型1)四种整数类型(byt ...

  4. ImportError: cannot import name 'Document'

    一种常见的原因是,程序文件的名字不对. 程序文件的名字不能和 import lib 里的名字冲突. 一个例子: 如果程序文件名字是 docx.py,程序又 from docx import Docum ...

  5. Linux高级调试与优化——内存管理

    1.物理地址和虚拟地址 Linux采用页表机制管理内存,32位系统中页大小一般为4KB,物理内存被划分为连续的页,每一个页都有一个唯一的页号. 为了程序的的可移植性,进程往往需要运行在flat mem ...

  6. zabbix服务端安装

    1.安装zabbix服务(1)先rpm安装lamp环境 yum install -y httpd mysql mysql-libs php php-mysql mysql-server php-bcm ...

  7. k8s中使用harbor

    参考地址:https://www.cnblogs.com/wayneiscoming/p/7716238.html .在harbor的ui界面上注册一个账号 姓名:zihao 全名:zhuzihao ...

  8. Docker容器启动报WARNING: IPv4 forwarding is disabled. Networking will not work

    错误: 解决: cat /etc/sysctl.conf net.ipv4.ip_forward=1net.ipv4.tcp_syncookies = 1net.ipv4.tcp_tw_recycle ...

  9. 【VS开发】error C2220: 警告被视为错误 - 没有生成“object”文件

    http://blog.csdn.net/cay22/article/details/5613625 这种错误的原因是:原因是该文件的代码页为英文,而我们系统中的代码页为中文. 解决方案: 1. 启动 ...

  10. go的变量定义

    package main //理解包的概念 import "fmt" var ( aa = 1 bb = "kkk" ss = true) func varia ...