简单了解 node net 模块
文章简单记录了对net 模块的理解分析。
- net模块
- 简单使用
- net.Server 对象
- net.Socket 对象
- 总结
1.1 net模块
net 模块用于创建基于流的 TCP 或 IPC 的服务器(net.createServer())与客户端(net.createConnection())。
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; }
每当有客户端连接时,就会调用onconnection函数,创建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); }
1.4. net.Socket对象
socket(通过 socket=new Socket() ) 是个双工流源码截取如下:
socket._handle上的对象是由C++中的Pipe、TCP实现。
然后利用C++中的Pipe、TCP实现,再一次扩展
所以socke实例有Writable,Readable,和TCP的相关功能函数。
1.5. 总结
TCP服务是一connection 为单位进行服务的。
要理解net模块或者net模块的API 除了多看文档,还可以看看TCP协议,链接建立握手,慢启动拥塞控制,Nagle算法解决的问题等等。
文章简单记录了对net 模块的理解分析。例子用词比较粗糙,理解不准确之处,还请教正。