Created
March 16, 2019 10:02
-
-
Save maolion/11158fe8eefaf7b4d7efb8719b0a9356 to your computer and use it in GitHub Desktop.
udp chunked data
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const shortId = require('shortid'); | |
const {CRC} = require('crc-full'); | |
const MTU = 22; | |
const HEAD_LENGTH = 21; | |
const PAYLOAD_LENGTH = MTU - HEAD_LENGTH; | |
const FLAG = 255; | |
const FLAG_BIT = new Uint8Array([255]); | |
const crc = new CRC('CRC8', 8, 0x07, 0x00, 0x00, false, false); | |
function sendData(data) { | |
let chunkSize = Math.ceil(data.length / PAYLOAD_LENGTH) | |
let cs = chunkSize.toString(32).padStart(2); | |
let id = shortId().padStart(13); | |
let chunks = []; | |
for (let offset = 0; offset < chunkSize; offset++) { | |
let co = (offset + 1).toString(32).padStart(2); | |
let chunk = Buffer.concat([ | |
Buffer.from(`${co}${cs}${id} `), | |
data.slice(offset, PAYLOAD_LENGTH + (PAYLOAD_LENGTH * offset)) | |
]); | |
let crcCode = crc.compute(chunk).toString(32).padStart(2); | |
chunk = Buffer.concat([ | |
FLAG_BIT, | |
Buffer.from(crcCode), | |
chunk | |
]); | |
chunks.push(chunk); | |
} | |
chunks.map(chunk => { | |
console.log(chunk.toString()) | |
}); | |
return chunks; | |
} | |
let map = new Map(); | |
function recvData(data) { | |
let x = data[0]; | |
if (x !== FLAG) { | |
return; | |
} | |
let crcCode = parseInt(data.slice(1, 3), 32); | |
if (isNaN(crcCode)) { | |
return; | |
} | |
let content = data.slice(3); | |
if (crc.compute(content) !== crcCode) { | |
return; | |
} | |
let offset = parseInt(content.slice(0, 2), 32); | |
let chunkSize = parseInt(content.slice(2, 4), 32); | |
let id =content.slice(4, 17).toString().trim(); | |
let body = content.slice(18); | |
let cache = map.get(id) || {length: 0}; | |
let index = offset - 1; | |
if (!cache[index]) { | |
cache.length++; | |
} | |
cache[offset - 1] = body; | |
if (cache.length === chunkSize) { | |
console.log(Buffer.concat(Array.from(cache)).toString()); | |
map.delete(id); | |
} else { | |
map.set(id, cache) | |
} | |
} | |
let chunks = sendData(Buffer.from('hello!')); | |
console.log('----') | |
for (let chunk of chunks) { | |
recvData(chunk); | |
} | |
console.log('----'); | |
for (let chunk of chunks.reverse()) { | |
recvData(chunk); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment