- Published on
Node 中的 net 模块
- Authors
- Name
- Et cetera
net 模块
回顾 HTTP 相关
普通模式
: 通过三次握手建立连接、四次挥手关闭连接,进行请求交互(次数多浪费带宽资源等等)长链接模式
: 通过三次握手建立连接,进行请求交互,但是不关闭连接,可以进行多次请求交互(connection: keep-alive)
,完成后四次挥手关闭连接
net 模块创建客户端
可以实现进程间的通信 IPC 和网络通信 TCP/IP
import * as net from 'net'
// 返回的 socket 是什么
// socket 是一个可读可写流(双工流)对象
// 作用:
// 通过向流中写入数据,向服务器发送数据
// 通过监听流的 data 事件,监听服务器返回的数据
// 是通过 TCP/IP 连接的远程服务器
const socket = net.createConnection({ host: 'github.com', port: 80 }, () => {
console.log('连接成功')
})
// 需要对数据进行写的操作,服务器才会做响应
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
}
})
// socket.write('a')
let receive = null
/**
* 提炼出响应信息的消息头和消息体
* @param response
*/
function parseResponse(response: string) {
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
}
// 这样表示发送的是一个 HTTP 请求
socket.write(`GET / HTTP/1.1
Host: localhost:8080
Connection: keep-alive
`)
socket.on('close', () => {
console.log(receive.body)
console.log('连接关闭')
})
net 模块创建服务端
net 创建服务器,并返回图片资源
import net from 'net'
import path from 'node:path'
import fs from 'node:fs'
const server = net.createServer()
server.listen(9527) // 服务器监听9527端口
server.on('listening', () => {
console.log('server listen 9527')
})
server.on('connection', (socket) => {
console.log('有客户端连接到服务器')
socket.on('data', async (chunk) => {
// console.log(chunk.toString('utf-8'))
const filename = path.resolve(__dirname, './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()
})
socket.on('end', () => {
console.log('连接关闭了')
})
})