码迷,mamicode.com
首页 > 其他好文 > 详细

TCP简单实现双工通讯

时间:2021-02-09 12:13:22      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:通讯   dex   ice   from   返回   for   creates   soc   ldb   

客户端,client.js

const net = require(‘net‘)
const socket = new net.Socket({})
const TestArr = [1,2, 3, 4]
socket.connect({
    host: ‘127.0.0.1‘,
    port: 4000
})
let seq = 0;
let oldBuffer = null  // 解决TCP粘包问题
socket.on(‘data‘, (buffer) => {
    if(oldBuffer) {
        buffer = Buffer.concat([oldBuffer, buffer])
    }
    let completeLength = 0

    while(completeLength = checkComplete(buffer)) {
        const package = buffer.slice(0, completeLength)
        buffer = buffer.slice(completeLength)
        const result = decode(package)
        console.log(`包${result.seq}, 返回值${result.data}`)
    }
    oldBuffer = buffer
})
function encode(index) {
    const body = Buffer.alloc(4)
    body.writeInt32BE(TestArr[index])
    const head = Buffer.alloc(6)
    head.writeInt16BE(seq)
    head.writeInt32BE(body.length, 2)

    const buffer = Buffer.concat([head, body])

    console.log(`包${seq}传输的名称id为${TestArr[index]}`);

    seq++;
    return buffer
}
function  decode(buffer) {
    const header = buffer.slice(0, 6)
    const seq = header.readInt16BE()
    const body = buffer.slice(6).toString()
    return  {
        seq,
        data:body
    }
}
function checkComplete(buffer) {
    if(buffer.length < 6) {
        return 0
    }
    const bodyLength = buffer.readInt32BE(2)
    return bodyLength + 6
}
for (let k = 0; k < 10; k++) {
    let index = Math.floor(Math.random() * TestArr.length)
    socket.write(encode(index));
}

服务器, server.js

const net = require(‘net‘)
const TestObj = {
    1: ‘anthony‘,
    2: ‘anthonyliu‘,
    3: ‘tencent‘,
    4: ‘pingan‘
}
const server = net.createServer((socket) => {
    let oldBuffer = null
    socket.on(‘data‘, function(buffer) {
        if(oldBuffer) {
            buffer = Buffer.concat([oldBuffer, buffer]);
        }

        let packageLength = 0;
        while(packageLength = checkComplete(buffer)) {
            const package = buffer.slice(0, packageLength)
            // 剩余buffer
            buffer = buffer.slice(packageLength)
            const result = decode(package)
            socket.write(encode(result.data,result.seq))
        }
        oldBuffer = buffer
    })
})
function checkComplete(buffer) {
    if(buffer.length < 6) {
        // 包不完整
        return 0
    } 
    // readInt32BE 读取buffer的 3 - 6位
    const bodyLength = buffer.readInt32BE(2)
    return 6 + bodyLength
}
function encode(index, seq) {
    const body = Buffer.from(TestObj[index])
    const head = Buffer.alloc(6)
    head.writeInt16BE(seq)
    head.writeInt32BE(body.length, 2)
    const buffer = Buffer.concat([head, body])
    // 不定长的body。tencent的长度为7
    console.log(`收到${seq}传输的名称id为${index},即将发送${TestObj[index]}`);
    return buffer
}
function  decode(buffer) {
    const header = buffer.slice(0, 6)
    const seq = header.readInt16BE()
    const body = buffer.slice(6).readInt32BE()
    return  {
        seq,
        data:body
    }
}
server.listen(4000)

 

TCP简单实现双工通讯

标签:通讯   dex   ice   from   返回   for   creates   soc   ldb   

原文地址:https://www.cnblogs.com/liuyinlei/p/14388914.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!