Node之net模块

Node之net模块

net 模块是建立在 tcp/ip 协议上的。同时还可以进行进程间的通信 ipc 。我们之前的 http 请求是一次请求一次响应。普通模式是三次握手之后进行一次请求和响应然后第四次挥手。长连接模式就是在握手和挥手之间不进行中断,直到客户端或者服务器有一方提出中断,使用 keep-alive连接方式。

而 tcp/ip 可以在握手和挥手之间传递任意数据,不受限制,不需要消息头,消息体。握手和挥手也是 tcp/ip 上的内容,它们在操作系统上被执行。我们只能在浏览器上看到请求和响应。

js 复制代码
const net = require('net')
const socket = net.createConnection({
    host: 'duyi.ke.qq.com',
    port: 80
}, () => {
    console.log('连接成功')
})
socket.on('data', chunk => {
    console.log(chunk.toString('utf-8'))
})
socket.write(`GET / HTTP/1.1
Host: duyi.ke.qq.com
Connection: keep-alive

`)

可以通过 net.createConnection 的方式创建一个客户端。会返回一个双工流 socket 。它是一个特殊的文件,与网卡相关联,可以随时写入读取。在进行读取前必须先写入数据。里面可以传入两个参数,第一个参数是配置对象,第二个参数是监听函数,它可以在完成连接之后调用。

这是因为 http 协议有固定的模式和格式。必须先进行请求然后才能拿到响应结果。请求的格式包括请求行,请求头,请求体。请求行一个换行到请求头,然后两个换行到请求体,请求体可以没有,但必须进行两次换行。

js 复制代码
const net = require('net')
const socket = net.createConnection({
    host: 'duyi.ke.qq.com',
    port: 80
}, () => {
    console.log('连接成功')
})
function parseResponse(response) {
    const index = response.indexOf('\r\n\r\n');
    const head = response.substring(0, index);
    const body = response.substring(index + 2);
    const headParts = head.split('\r\n');
    const headerArray = headParts.slice(1).map(str => {
        return str.split(':').map(s => s.trim())
    })
    const header = headerArray.reduce((a, b) => {
        a[b[0]] = b[1];
        return a;
    }, {})
    return {
        header,
        body: body.trimStart()
    }
}
function isOver() {
    const contentLength = receive.header['Content-Length'];
    const curReceivedLength = Buffer.from(receive.body, 'utf-8').byteLength;
    console.log(contentLength, curReceivedLength);
    return curReceivedLength > contentLength;
 }
let receive = null;
socket.on('data', chunk => {
    const response = chunk.toString('utf-8')
    if (!receive) {
        //第一次接受数据
        receive = parseResponse(response)
        if (isOver()) {
            socket.end()
        }
        return;
    }
    receive.body += response;
    if (isOver()) {
        socket.end()
        return;
    }
    console.log('来自服务器的消息');
});
socket.write(`GET / HTTP/1.1
Host: duyi.ke.qq.com
Connection: keep-alive

 `);
socket.on('close', () => {
    console.log(receive.body)
    console.log('关闭了');
});

我们将 header 里面的东西提取出来,变成一个对象。并找到对象里的 Content-Length 然后看是否当前的字符长度达到了要求的长度。如果第一次已经达到,就直接结束,如果没有达到,就在 body 里不断加入拿到的响应结果加进去,直到达到要求的字符长度。并在最后结束的时候将 body 输出。

js 复制代码
const fs = require('fs');
const path = require('path');
const server = net.createServer();
server.listen(8000);
server.on('listening', () => {
    console.log("server listen 8000")
})
server.on("connection", (socket) => {
    console.log("有新的连接");
    socket.on("data", async chunk => {
        const filename=path.resolve(__dirname, "./myfiles/avatar.jpeg");
        const bodyBuffer = await fs.promises.readFile(filename);
        const headBuffer = Buffer.from(`HTTP/1.1 200 OK
Content-Type: image/jpeg

`,
          "utf-8"
        );
        const result = Buffer.concat([headBuffer, bodyBuffer]);
        socket.write(result);
        socket.end();
    });
});
server.on("close", () => {
    console.log("server close")
});

创建一个服务器,可以传入一个监听函数,表示服务器是否创建。服务器需要监听一个端口,并且在监听之后可以通过 listening 事件得知。

当与客户端成功连接之后,会创建一个 socket ,即使是同一个客户端断开之后,也会重新创建一个 socket ,socket 在一次连接过后或者长时间断开之后销毁。使用 connection 可以监听连接。

可以读取客户端传来的 socket ,然后再写入 socket 作为响应结果。

在连接结束之后,关闭服务器。

相关推荐
东东5162 小时前
基于ssm的网上房屋中介管理系统vue
前端·javascript·vue.js
harrain3 小时前
什么!vue3.4开始,v-model不能用在prop上
前端·javascript·vue.js
阿蒙Amon8 小时前
TypeScript学习-第7章:泛型(Generic)
javascript·学习·typescript
睡美人的小仙女1278 小时前
Threejs加载环境贴图报错Bad File Format: bad initial token
开发语言·javascript·redis
fanruitian8 小时前
uniapp android开发 测试板本与发行版本
前端·javascript·uni-app
rayufo8 小时前
【工具】列出指定文件夹下所有的目录和文件
开发语言·前端·python
RANCE_atttackkk8 小时前
[Java]实现使用邮箱找回密码的功能
java·开发语言·前端·spring boot·intellij-idea·idea
摘星编程9 小时前
React Native + OpenHarmony:Timeline垂直时间轴
javascript·react native·react.js
2501_9445255410 小时前
Flutter for OpenHarmony 个人理财管理App实战 - 支出分析页面
android·开发语言·前端·javascript·flutter
jin12332211 小时前
React Native鸿蒙跨平台完成剧本杀组队详情页面,可以复用桌游、团建、赛事等各类组队详情页开发
javascript·react native·react.js·ecmascript·harmonyos