NodeJs(1)-net module

Get into the habit of writing together! This is the 4th day of my participation in the "Nuggets Daily New Plan·April Update Challenge", click to view the details of the event .

1 Introduction

This is the first article in the nodeJs series. When I read the tutorials before, many of them started from the IO, buffer, path, event, fs, process, node event loop mechanism. These are indeed the main dependencies of node development. Development dependencies. But I'm in a hurry, since I learned about node, it means that node can do the backend, but the first half of these courses are talking about its capabilities, that is, the module introduction on how to communicate with the client at the end.

I feel very uncomfortable, so when I write my own summary, I must write a module that communicates between the server and the client to be comfortable. Even if the process involves the knowledge points of the event module and the fs module, it can be put on hold for the time being, and only from the whole Understand nethow modules communicate.

2. OSI seven-layer protocol model

If you want to learn the communication module, you have to understand the network communication model. If you want to remember the network communication model, you have to actually operate to assist memory. This is the focus of the interview. There is a lot of content in this section. It is also said that systematic learning is required. Here is just a brief mention.

Send this old picture:

image_1649504393157_0.png

For our front-end, we need to remember the system results of the TCP/IP protocol suite.

  • Application layer: http (port 80), FTP (21), SMTP (send mail), POP (receive mail), DNS

  • Transport Layer: TCP/UDP

  • Internet layer: IP, ICMP (is a subsidiary protocol of the IP layer)

  • Data link layer: PPP, SLIP

  • Physical layer: The network has transmission methods such as twisted pair, coaxial cable, optical fiber, etc., following the ISO2110 specification

From ICMPthis protocol attached to the IP protocol, we can know that there is no need to compete too much with the layering of the network protocol. ICMPObviously, the IP protocol is needed as the basis, but it is also planned as the network layer. Our correct understanding of the OSI model, I think it should be It is more meaningful to use the OSI model for problem analysis than for so-called layering of protocols.

TCP/IP 协议簇 并不是只是指 TCP 和 IP 协议,只是因为这两个协议过于出圈,所以就用 TCP/IP 来统称互联网相关联的协议集合起来. 还有另外一种说法是,在使用 TCP/IP 协议过程中使用到的协议族的统称.

而客户端和服务端的传输流如下

Picture_1649505674172_0.png

如果角色变成发送者接受者的时候,传输流如下图:

Picture_2_1649505888621_0.png

 可以看出来传输的过程中,从发送端开始,没经过一层协议都会加上所需要的首部信息.层层把关,层层加码. 然后到了接收端的时候, 就反而行之, 每经过一层都剥去对应的首部. 只等到最后拿到的 HTTP 数据.

上面图片出自《图解 HTTP》

上面就是大体的网络协议模型.

疑惑: 为什么书上和很多地方在把 OSI 体系结果中合并成 TCP/IP 五层协议之后,网络层的名称会变成网际层呢?

3. TCP 连接

image_1649509541746_0.png

第一次握手: 客户端向服务端发送 SYN 标志位(序号是 J), 并进入 SYN_SENT 状态(等待服务端确认状态)

第二次握手: 服务端收到来自客户端的 SYN J, 服务端会确认该数据包已收到并发送 ACK 标志位(序号是 J + 1)和 SYN 标志位(序号是 K), 随后进入 SYN_REVD 状态(请求接受并等待客户端确认状态)

第三次握手: 客户端进入连接建立状态后,向服务端发送 ACK 标志位(K+ 1) , 确认客户端已收到建立连接,服务器收到 ACK 标志后,服务端进入连接已建立状态.

J 和 K 都是为了确立是谁在请求. SYN 和 ACK 的结构没有什么不同,只是发送的对象不一样.

4. net 模块

net模块就是对于上面 TCP 连接的具体实现.

首先, 学习 API 依旧推荐直接进入官方文档. 其中中文文档内容不会是最新版本的

在学习的时候,能够有时间看英文文档就尽量看英文文档. 对于这一点我坚持了半年. 从一开始看不下去,直到现在能够可以忍住不舒适感看下去. 半年时间进步就很明显了. 而且这种不舒适感是一件好事,说明这个不是你的舒适区,毕竟勇于跨过自己的舒适区才是进步的源泉

接下来,进行正题.既然要学习通信,那么我们就需要两个对象来模拟客户端和服务端.分别建立client.jsservice.js两个文件. 通过命令行创建:

touch client.js && touch service.js
复制代码

4.1 service.js 部分

 引入net模块,并让服务器进入LISTENT状态, 以及配置端口号和 HOST 地址(手动略过 DNS 解析过程), 等待客户端的召唤

const net = require("net");
const post = 3306;
const host = "127.0.0.1";

const server = net.createServer();
server.listen(post, host);
复制代码

此时服务器对应了 TCP 连接中服务器LISTEN状态.

随后监听一些必要的事件,也就是 server 提供的钩子. (属于 event 相关知识)

server.on("listening", () => {
  console.log("服务器已经可以连接啦");
});

server.on("connection", (socket) => {
  console.log("有客户端来访咯");
});

server.on("close", () => {
  console.log("服务器关闭了");
});

server.on("error", (error) => {
  console.log("服务器出错啦: ", error); // error 有错误的信息
});
复制代码

上面这一串代码涉及到了,

  • listening: 监听端口后出发的事件
  • connection: 有客户端来访的时候触发事件
  • close: 服务器关闭触发
  • error: 服务器出错触发

对于close我们需要注意的是,后台大哥一般是直接

ps
kill -9 pid
复制代码

通过杀死线程的方式来进行的

connection狗子中, 形参是 socket 命名. 它的中文翻译为嵌套字, 被 node 封装成了 stream(流).在可以粗浅的理解为就是客户端发送过来的数据. 这是这个数据自身是有方法的. 我在connection中对socket来进行处理

server.on("connection", (socket) => {
  console.log("有客户端来访咯");

  socket.on("data", (data) => {
    console.log(data); // 客户端发送过来的数据
  });
});
复制代码

stream 以后的文章会进行介绍.

服务端既然能够接受客户端发过来的数据,自然也能够给客户端回复. 在socket.on中写入(当然也可以写在外面):

socket.write("我已经收到你的服务器了哦,客户端");
复制代码

此时如果客户端已经完成了数据的接受,然后关闭了连接.我们可以也可以通过socket.on('close‘)钩子监听到:

socket.on("close", () => {
  console.log("客户端把另外一头的流给关了");
});
复制代码

For socketa summary of events put client.jsin. service.jsEverything at this point is as follows:

const net = require("net");
const post = 3306;
const host = "127.0.0.1";

const server = net.createServer();
server.listen(post, host);

server.on("listening", () => {
  console.log("服务器已经可以连接啦");
});

server.on("connection", (socket) => {
  console.log("有客户端来访咯");

  socket.on("data", (data) => {
    console.log(data); // 客户端发送过来的数据

    socket.write("我已经收到你的服务器了哦,客户端");
  });

  socket.on("close", () => {
    console.log("客户端把另外一头的流给关了");
    server.close(); // 客户端已经不要数据了,那么我们就把服务器给关闭了吧
  });
});

server.on("close", () => {
  console.log("服务器关闭了");
});

server.on("error", (error) => {
  console.log("服务器出错啦: ", error); // error 有错误的信息
});
复制代码

4.2 client.js section

The client side is much simpler.

const net = require("net");
const post = 3306;
const host = "127.0.0.1";

const socket = net.connect(post, host);

socket.on("connect", () => {
  console.log("已经连接到服务器了哦");
});

socket.write("服务器, 我来了");
socket.on("data", (data) => {
  console.log(data.toString());
  socket.end();
});

socket.on("close", () => {
  console.log("连接已关闭了");
});
复制代码

socketSummary of events for

  • connect: Triggered on success and server connection
  • data: Receive the parameters sent by the server
  • end: Triggered after data is received
  • close: socket close trigger

service.jsAnd client.jsthe frameworks have been written, those run them successively while opening two terminals:

node service.js
node client.js
复制代码

Check the printed results for yourself.

The framework of the entire TCP connection has been basically completed. Of course, the actual production is far more than that. It also needs to deal with sticky packets, unpacking/packaging, heartbeat packets, and so on.

netThe next article will continue to improve the description of the module in combination with the actual browser initiating the request .

Guess you like

Origin juejin.im/post/7084618854801866765