likes
comments
collection
share

node.js之net模块

作者站长头像
站长
· 阅读数 62

net

net模块是Node.js的核心模块之一,net模块主要用于创建TCP服务器和TCP客户端,以及处理网络通信。

net模块主要包含两部分:

  • net.Server类:通常用于创建一个 TCP 或本地服务器,内部通过socket来实现与客户端的通信。
  • net.Socket类:TCP或本地 socket的node版实现,net.Socket 实例实现了全双工的stream接口。net.Socket 可以由用户创建并直接用于与服务器交互,例如,它由 net.createConnection() 返回,因此用户可以使用它与服务器对话。它也可以由 Node.js 创建并在收到连接时传递给用户,例如,它被传递给 net.Server 上触发的 connection事件的监听器,因此用户可以使用它与客户端进行交互。

Socket 是对 TCP/IP 协议族的一种封装,是应用层与TCP/IP协议族通信的中间软件抽象层。它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。 Socket 还可以认为是一种网络间不同计算机上的进程通信的一种方法,利用三元组(ip地址,协议,端口)就可以唯一标识网络中的进程,网络中的进程通信可以利用这个标志与其它进程进行交互。

TCP

TCP是一种面向连接的、可靠的传输协议,用于在计算机网络上进行数据传输,是应用层和网络层之间的传输层协议。

TCP的特点:

  • 可靠性:TCP通过使用确认机制、序列号和重传策略来确保数据的可靠传输。它可以检测并纠正数据丢失、重复、损坏或失序的问题。
  • 面向连接:在进行数据传输之前,TCP需要在发送方和接收方之间建立一个连接。连接的建立是通过三次握手来完成的,确保双方都准备好进行通信。
  • 全双工通信:TCP支持双方同时进行双向通信,即发送方和接收方可以在同一时间发送和接收数据。
  • 流式传输:TCP一次传输的报文长度有限制,若太大则需要分块、分次传输。TCP将数据视为连续的字节流进行传输,而不是离散的数据包。
  • 拥塞控制:TCP具备拥塞控制机制,用于避免网络拥塞和数据丢失。它通过动态调整发送速率、使用拥塞窗口和慢启动算法等方式来控制数据的发送速度。

node.js之net模块

node.js之net模块

net模块方法和属性

net.createServer([options][, connectionListener]):两个参数都是可选的,创建一个 TCP 服务器。参数 connectionListener 是函数类型,是connection 事件监听器的回调函数。

net.createConnection(options[, connectionListener]):创建一个到端口 port 和 主机 host的 TCP 连接。 host 默认为 'localhost'。第一个参数是配置对象,包含端口port和主机host的配置;第二个参数可选,connectListener 将会作为监听器添加到connect事件。返回 net.Socket类。

net.isIP(input):检测输入的是否为 IP 地址。 IPV4 返回 4, IPV6 返回 6,其他情况返回 0。

net.isIPv4(input):如果输入的地址为 IPV4, 返回 true,否则返回 false。

net.isIPv6(input):如果输入的地址为 IPV6, 返回 true,否则返回 false。

net.Server类

net.createServer([options][, connectionListener])创建了一个TCP 服务器,就是net.Server类的实例sever对象。

方法和属性

server.listen():启动监听连接的服务器,可以监听 TCP 或 IPC 服务器,具体取决于它监听的内容。

  • server.listen([port[, host[, backlog]]][, callback]) 用于 TCP 服务器的监听。监听指定端口port 和主机host。 默认情况下 host 接受任何 IPv4 地址的直接连接。端口 port 为 0 时,则会分配一个随机端口。
  • server.listen(path[, backlog][, callback])用于 IPC服务器的监听

server.listen()函数是异步的。当服务器开始监听时,将触发 listening 事件,最后一个参数 callback 将被添加为 listening事件的监听器。

server.close([callback]):关闭服务器,停止接收新的客户端请求,保持现有连接。注意事项如下:

  • 对正在处理中的客户端请求,服务器会等待它们处理完(或超时),然后再正式关闭。
  • 正常关闭的同时,callback 会被执行,同时会触发 close 事件。
  • 异常关闭的同时,callback 也会执行,同时将对应的 error 作为参数传入。比如还没调用server.listen() 之前,就调用了server.close()

已调用server.listen()正常关闭,close事件触发,然后callback执行,error参数为undefined。未调用server.listen()异常关闭,close事件触发,然后callback执行,error为具体的错误信息。

server.close()是异步函数,当所有连接结束的时候服务器会关闭,并会触发close事件,参数 callback 将被添加为 close事件的监听器。

server.address():返回服务端的地址信息,比如绑定的ip地址、端口、协议族名等

console.log( server.address() );
// 输出如下 { port: 3000, family: 'IPv4', address: '127.0.0.1' }

server.unref():如果这是事件系统中唯一一个活动的服务器,调用 unref 将允许程序退出。

server.ref():与 unref 相反,如果这是唯一的服务器,在之前调用了 unref的服务器上调用 ref 将不会让程序退出(默认行为)。如果服务器已经被 ref,则再次调用 ref 并不会产生影响。

ref主要用于将server 加入事件循环以及unref将server从事件循环里面剔除,影响就在于会不会影响进程的退出。

事件

  • listening:调用 server.listen(),正式开始监听请求的时候触发。
  • connection:当有新的请求进来时触发,参数为请求相关的 socket。
  • close:服务端关闭的时候触发。注意,如果存在连接,这个事件不会被触发直到所有的连接关闭。
  • error:服务出错的时候触发,比如监听了已经被占用的端口。

net.Socket类

net.Socket类的实例对象是 TCP 或 UNIX Socket 的抽象。net.Socket 实例实现了一个双工流接口。实例对象可以由用户创建,使用net.createConnection(options[, connectionListener]) 或者由 Node 创建,并通过 connection 服务器事件传递给用户。

方法和属性

连接相关

socket.connect():在给定套接字上启动连接。

  • socket.connect(port[, host][, connectListener]) 用于 TCP 连接。指定端口 port 和 主机 host,参数 host 默认为 localhost。
  • socket.connect(path[, connectListener]) 用于 IPC 连接,打开指定路径的 unix socket。

TCP用主机的IP地址加上主机上的端口号作为TCP连接的端点,这种端点就叫做套接字。套接字用IP地址:端口号表示

socket.setTimeout(timeout[, callback]):用来进行连接超时设置。socket 闲置时间超过 timeout 毫秒后 ,将 socket 设置为超时。

socket.setKeepAlive([enable][, initialDelay]):用来禁用或启用长连接功能,并在发送第一个在闲置 socket 上的长连接 probe 之前,可选地设定初始延时。默认为 false。 设定 initialDelay (毫秒),来设定收到的最后一个数据包和第一个长连接probe之间的延时。将 initialDelay 设为0,将会保留默认(或者之前)的值。默认值为0。

socket.destroy():当错误发生时,用来销毁socket。确保没有 I/O 活动在这个套接字上,只有在错误发生情况下才需要。(处理错误等等)。

数据读、写相关

socket.write(data[, encoding][, callback]):在 socket 上发送数据。第二个参数指定了字符串的编码,默认是 UTF8 编码。

socket.end([data][, encoding]):半关闭 socket。例如,它发送一个 FIN 包,可能服务器仍在发送数据。

socket.pause():暂停读取数据。就是说,不会再触发 data 事件。对于控制上传非常有用。

socket.resume() :调用 pause() 后想恢复读取数据。

socket.setEncoding([encoding]):设置编码

socket.setNoDelay([noDelay]):禁用纳格(Nagle)算法。默认情况下 TCP 连接使用纳格算法,在发送前会缓冲数据。将 noDelay 设置为 true 将会在调用 socket.write() 时立即发送数据。noDelay 默认值为 true。

数据属性相关

socket.bufferSize:该属性显示了要写入缓冲区的字节数。

socket.bytesRead:接收到得字节数。

socket.bytesWritten:发送的字节数。

事件循环相关

socket.unref():如果这是事件系统中唯一一个活动的服务器,调用 unref 将允许程序退出。如果服务器已被 unref,则再次调用 unref 并不会产生影响。

socket.ref():与 unref 相反,如果这是唯一的服务器,在之前被 unref 了的服务器上调用 ref 将不会让程序退出(默认行为)。如果服务器已经被 ref,则再次调用 ref 并不会产生影响。

地址相关

socket.address():操作系统返回绑定的地址,协议族名和服务器端口。返回的对象有 3 个属性,比如{ port: 12346, family: 'IPv4', address: '127.0.0.1' }

socket.remoteAddress:远程的 IP 地址字符串,例如:'74.125.127.100' or '2001:4860:a005::68'

socket.remoteFamily:远程IP协议族字符串,比如 IPv4或者IPv6。

socket.remotePort:远程端口,数字表示,例如:80 or 21。

socket.localAddress:网络连接绑定的本地接口 远程客户端正在连接的本地 IP 地址,字符串表示。例如,如果在监听'0.0.0.0'而客户端连接在'192.168.1.1',这个值就会是 '192.168.1.1'。

socket.localPort:本地端口地址,数字表示。例如:80 or 21。

事件

  • data:当收到另一侧传来的数据时触发。
  • connect:当连接建立时触发。
  • close:连接断开时触发。如果是因为传输错误导致的连接断开,则参数为error。
  • end:当连接另一侧发送了 FIN 包的时候触发。默认情况下(allowHalfOpen == false),socket会完成自我销毁操作。但也可以把 allowHalfOpen 设置为 true,这样就可以继续往socket里写数据。当然,最后需要手动调用 socket.end()
  • error:当有错误发生时,就会触发,参数为error。
  • timeout:提示用户,socket 已经超时,需要手动关闭连接。
  • drain:当写缓存空了的时候触发。(不是很好描述,具体可以看下stream的介绍)
  • lookup:域名解析完成时触发。

TCP使用场景

服务端之间通信

服务端之间的通信可以直接使用TCP协议,而不需要上升到http协议。比如A服务器提供的接口B服务器可以不用通过调用接口的形式。

server.js:创建一个TCP服务,并且发送套接字,监听端口号3000

import net from 'net'
// 创建TCP服务
const sever = net.createServer(socket => {
    // 函数参数中的socket参数可以用于接受和发送消息
    // 发送消息
    setInterval(() => {
        socket.write('hello');
    },6000);
    // 接受消息
    socket.on('data',(e) => {
        console.log(e.toString());
    })
});
// 监听端口
sever.listen(3000,() => {
    console.log('3000 端口的服务正在监听');
});

client.js:连接server端,并且监听返回的数据

import net from 'net'
// 创建客户端,监听返回的数据
const client = net.createConnection({
    // 配置对象包含需要监听服务器的主机和端口
    port:3000,
    host:'127.0.0.1'
});
// 监听data事件,接收到数据时触发
client.on('data',(e) => {
    console.log(e.toString());
});
// 客户端发送消息
client.write('world');

node.js之net模块

在传输层实现应用层的http协议

创建一个TCP服务

import net from 'net'
// 给客户端返回的数据
const html = `<h1>暗号</h1><h2>tiamo</h2>`;
// 给客户端返回的HTTP响应报文
const response = [
    'HTTP/1.1 200 OK', // 响应行:http版本号、状态码
    'Content-Type: text/html;charset=utf-8', // 响应头:返回的数据类型
    `Content-Length: ${html.length}`, // 响应头:返回数据的长度
    '\r\n', // 换行,响应头后面换行接响应体
    html // 响应体,返回的具体数据位于响应体
];
// 创建TCP服务
const http = net.createServer(socket => {
    // 函数参数中的socket参数可以用于接受和发送消息
    // 接受消息
    socket.on('data',(e) => {
        // 此时接受的消息就是HTTP请求报文,包含请求行、请求头、请求体
        console.log(e.toString());
        // 发送GET请求就返回数据
        if(/GET/.test(e.toString())){
            // 发送消息
            socket.write(response.join('\r\n'));
            // 消息发送完成后,断开链接,避免客户端还处于链接状态
            socket.end();
        }
    })
});
// 监听端口
http.listen(8089,() => {
    console.log('8089 端口的服务正在监听');
});

使用浏览器发送了一个http的get 请求,可以通过关键字get返回相关的内容例如html

node.js之net模块

net.createServer创建 Unix 域套接字并且返回一个server对象接受一个回调函数,回调函数的参数是socket。

socket可以监听很多事件

  1. close 一旦套接字完全关闭就触发
  2. connect 当成功建立套接字连接时触发
  3. data 接收到数据时触发
  4. end 当套接字的另一端表示传输结束时触发,从而结束套接字的可读端
转载自:https://juejin.cn/post/7374239850077159476
评论
请登录