最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - nodejs socket programming - send data length - Stack Overflow

programmeradmin1浏览0评论

I have a server listening on specific port and expects mands the following way -

First four bytes should contain the length of the mand and remaining bytes contains the actual mand. For example:

If the mand I want to send is {cmd:"EL",ptno:1234}, the first four bytes I send should contain the number 20 in them in big-endian notation as the mand length is 20 as the mands are in UTF-8 format. The remaining bytes I send will have the mand in them.

I want to know how to do this in nodejs. Also when the server sends data back, I need to read the first four bytes and determine the data length and read the socket input stream accordingly. Please help.

I have a server listening on specific port and expects mands the following way -

First four bytes should contain the length of the mand and remaining bytes contains the actual mand. For example:

If the mand I want to send is {cmd:"EL",ptno:1234}, the first four bytes I send should contain the number 20 in them in big-endian notation as the mand length is 20 as the mands are in UTF-8 format. The remaining bytes I send will have the mand in them.

I want to know how to do this in nodejs. Also when the server sends data back, I need to read the first four bytes and determine the data length and read the socket input stream accordingly. Please help.

Share Improve this question edited Sep 22, 2016 at 1:51 ZachB 15.5k5 gold badges66 silver badges93 bronze badges asked Jun 26, 2016 at 14:13 Vijay MuvvaVijay Muvva 1,0933 gold badges17 silver badges34 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 7

I've did a lib that does EXACTLY what you need: https://www.npmjs./package/node-easysocket (except by writing 4 bytes in Little Endian, but it is very easy to fix)

About your question, here we go:

For send a message, is much more easy than receive, you just need convert you message to a ByteArray and prepend an integer (4 bytes Big Endian) containing the size of your ByteArray + 4:

var buffer = new Buffer("Hello World or a JSON String", "binary");

//create a buffer with +4 bytes
var consolidatedBuffer = new Buffer(4 + buffer.length);

//write at the beginning of the buffer, the total size
consolidatedBuffer.writeInt32BE(buffer.length, 0);

//Copy the message buffer to the consolidated buffer at position 4     (after the 4 bytes about the size)
buffer.copy(consolidatedBuffer, 4);

//Send the consolidated buffer
socket.write(consolidatedBuffer, function(err) {
     if (err) console.log(err)
});

if you want to read, it will be a bit more plex, because you have the possibility to you read a buffer spliced in chunks.

Example: My buffer have 10mb of size but my network connection can transfer ~100 bytes per second, so the server will receive a lot of pieces of data and you will need store them until it plete the necessary size according the length informed in the first 4 bytes.

The Javascript is a dynamic language, so I can create a runtime property the the socket object to store the collected chunks:

socket.on('data', function(data) {
    console.log("server bytes in:"+data.length);
    receive(socket,data);
});


function receive(socket, data){
    //Create a chunk prop if it does not exist
    if(!socket.chunk){
        socket.chunck = {
            messageSize : 0,
            buffer: new Buffer(0),
            bufferStack: new Buffer(0)
        };
    }
    //store the ining data
    socket.chunck.bufferStack = Buffer.concat([socket.chunck.bufferStack, data]);
    //this is to check if you have a second message ining in the tail of the first
    var reCheck = false;
    do {
        reCheck = false;
        //if message size == 0 you got a new message so read the message size (first 4 bytes)
        if (socket.chunck.messageSize == 0 && socket.chunck.bufferStack.length >= 4) {
            socket.chunck.messageSize = socket.chunck.bufferStack.readInt32BE(0);
        }

        //After read the message size (!= 0) and the bufferstack is pleted and/or the ining data contains more data (the next message)
        if (socket.chunck.messageSize != 0 && socket.chunck.bufferStack.length >= socket.chunck.messageSize + 4) {
            var buffer = socket.chunck.bufferStack.slice(4, socket.chunck.messageSize + 4);
            socket.chunck.messageSize = 0;
            socket.chunck.bufferStack = socket.chunck.bufferStack.slice(buffer.length + 4);
            onMessage(socket, buffer);
            //if the stack contains more data after read the entire message, maybe you got a new message, so it will verify the next 4 bytes and so on...
            reCheck = socket.chunck.bufferStack.length > 0;
        }
    } while (reCheck);
}

function onMessage(socket, buffer){
    console.log("message received from: "+socket+" with data:"+buffer.toString()+");
}
发布评论

评论列表(0)

  1. 暂无评论