socket-sync-buffer, nodejs平台 promise风格读写socket库

socket-sync-buffer

同步操作socket, 基于 promise, 见例子 examples

网址: https://gitee.com/linuxmail/node-socket-sync-buffer

基本用法

npm i socket-sync-buffer

创建对象

const socketSyncBuffer = require("socket-sync-buffer").socketSyncBuffer

// host: string, 地址
// port: number, 端口
// ssl?: boolean, 是否开启ssl
// timeout?: number, 读写超时(毫秒)
// rejectUnauthorized?: boolean, 如果证书有问题是否拒绝连接
let socket = new socketSyncBuffer({ host: "127.0.0.1", port: 465, ssl: false, timeout: 0 })

连接

返回值是 boolean 类型, 返回 false 表示连接失败, 返回 true 表示成功

let res = await socket.connect()

读数据

返回 null 表示网络失败, 或连接关闭, 否则表示成功, 类型为 Buffer

// 读一行, 
let res = await socket.gets()
let res = await socket.readDelimiter("\n")

// 最多读取 maxSize个字符, maxSize为 0 表示不限制 
let res = await socket.readDelimiter(delimiter: string, maxSize: number = 0)

// 读指定长度的数据
let res = await socket.readn(size: number)

// 读数据, 数据长度不定
let res = await socket.read()

写数据

返回值是 boolean 类型, 返回 false 表示网络错误,或连接关闭,返回 true 表示成功

// 写 string
let res = await socket.write(str: string)
// 写 Buffer
let res = await socket.writeBuffer(buf: Buffer)
// flush 写缓存
let res = await socket.flush()

发起 ssl 连接

返回值是 boolean 类型, 返回 false 表示网络错误,或连接关闭,返回 true 表示成功

let res = await socket.tlsConnect()

属性

返回值是 boolean 类型

// 是否出错, 一般指的是网络错误
let res = socket.isError()
// 是否超时错误
let res = socket.isTimeout()
// 是否连接关闭
let res = socket.isClosed()

其他可读

// 是否有真实数据可读
await trueDataReadable()

有的时候服务会主动返回数据, 用下面这个方法检测

执行一次, 只生效一次, 可读或出错的时候执行 handler,

如果 handler 为 undefined, 则使用上一次的 handler

void setOnExtraDataReadableHandlerOnce(handler: (() => any) | undefined)

例子, smtp 客户端协议(部分)

import { socketSyncBuffer } from "../dist/index.mjs"

let argv = process.argv

function showUsage() {
    console.log(argv[0], argv[1], "smtp_host port [ SSL / STARTTLS ]")
    console.log("EXAMPLES:")
    console.log(argv[0], argv[1], "127.0.0.1 25")
    console.log(argv[0], argv[1], "127.0.0.1 25 STARTTLS")
    console.log(argv[0], argv[1], "127.0.0.1 465 SSL")
    process.exit(1)
}

async function do_test_cmd_ehlo(socket) {
    console.log("")
    if (! await socket.write("ehlo xxx\r\n")) {
        console.log("send ehlo xxx, error")
        return false
    }
    console.log("send ehlo xxx, success")

    while (1) {
        let res = await socket.gets()
        if (res === null) {
            console.log("recv ehlo, error")
            return false
        }
        console.log("recv ehlo: ", res.toString().trim())
        if (res.toString()[0] != "2") {
            break
        }
        if (res.toString().startsWith("250 ")) {
            break
        }
    }

    return true
}

async function do_test_cmd_STARTTLS(socket) {
    console.log("")
    if (!await socket.write("STARTTLS\r\n")) {
        console.log("send STARTTLS, error")
        return false
    }
    let res = await socket.gets()
    if ((res === null) || (res.length < 1)) {
        console.log("recv STARTTLS response, error")
        return false
    } else {
        let s = res.toString()
        if (s[0] != "2" && s[0] != "3") {
            console.log("recv STARTTLS: ", s)
        } else {
            if (! await socket.tlsConnect()) {
                console.log("STARTTLS handshake, error")
                return false
            }
            console.log("STARTTLS handshake, success")
        }
    }
    return true
}

async function do_test(attrs) {
    let socket = new socketSyncBuffer({ host: attrs.host, port: attrs.port, ssl: attrs.ssl, timeout: 10000 })

    if (! await socket.connect()) {
        console.log("connect", attrs.host + ":" + attrs.port + ", error")
        return
    }

    console.log("")
    let res = await socket.gets()
    if (res === null) {
        console.log("recv welcome, error")
        return
    }
    console.log("recv welcome: ", res.toString().trim())

    if (! await do_test_cmd_ehlo(socket)) {
        return
    }

    if (argv[4] === "STARTTLS" && attrs.ssl !== true) {
        if (! await do_test_cmd_STARTTLS(socket)) {
            return
        }
        if (! await do_test_cmd_ehlo(socket)) {
            return
        }
    }

    console.log("")
    if (!await socket.write("quit\r\n")) {
        console.log("send quit, error")
        return
    }
    console.log("send quit, success")
    if ((res = await socket.gets()) === null) {
        console.log("recv quit, error")
        return
    }
    console.log("recv quit, success")

    console.log("")
    console.log("status, closed: ", socket.isClosed())
    console.log("status, error: ", socket.isError())

    console.log("")
    console.log("smtp 协议完成了, 一般情况,服务器已经关闭了连接")
    console.log("再次读一次, 则应该返回错误")
    if ((res = await socket.gets()) === null) {
        console.log("recv, error")
    }
    console.log("")
    console.log("status, closed: ", socket.isClosed())
    console.log("status, error: ", socket.isError())
}

if (argv.length < 4) {
    showUsage()
}

do_test({ host: argv[2], port: parseInt(argv[3]), ssl: (argv[4] === "SSL") }).then((a) => {
    console.log("\ntest over\n")
})
```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值