Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/463.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript nodejs套接字编程-发送数据长度_Javascript_Node.js_Sockets_Io - Fatal编程技术网

Javascript nodejs套接字编程-发送数据长度

Javascript nodejs套接字编程-发送数据长度,javascript,node.js,sockets,io,Javascript,Node.js,Sockets,Io,我有一个服务器在监听特定的端口,并期望通过以下方式接收命令- 前四个字节应包含命令的长度,其余字节包含实际命令。例如: 如果我要发送的命令是{cmd:“EL”,ptno:1234},那么我发送的前四个字节中应该包含数字20,以大端表示法表示,因为命令的长度是20,因为命令是UTF-8格式。我发送的其余字节将包含命令 我想知道如何在nodejs中实现这一点。此外,当服务器发回数据时,我需要读取前四个字节,确定数据长度,并相应地读取套接字输入流。请帮忙。我已经做了一个lib,它可以完全满足您的需要:

我有一个服务器在监听特定的端口,并期望通过以下方式接收命令-

前四个字节应包含命令的长度,其余字节包含实际命令。例如:

如果我要发送的命令是
{cmd:“EL”,ptno:1234}
,那么我发送的前四个字节中应该包含数字20,以大端表示法表示,因为命令的长度是20,因为命令是UTF-8格式。我发送的其余字节将包含命令


我想知道如何在nodejs中实现这一点。此外,当服务器发回数据时,我需要读取前四个字节,确定数据长度,并相应地读取套接字输入流。请帮忙。

我已经做了一个lib,它可以完全满足您的需要:(除了用Little Endian写4个字节,但它很容易修复)

关于你的问题,我们开始:

对于发送消息,要比接收消息容易得多,只需将消息转换为ByteArray,并预先输入一个整数(4字节Big-Endian),其中包含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)
});
如果你想读,它会有点复杂,因为你有可能读一个拼接成块的缓冲区

示例:我的缓冲区大小为10mb,但我的网络连接每秒可以传输约100个字节,因此服务器将接收大量数据,您需要存储这些数据,直到它根据前4个字节中通知的长度完成必要的大小

Javascript是一种动态语言,因此我可以在socket对象中创建一个运行时属性来存储收集的块:

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 incoming data
    socket.chunck.bufferStack = Buffer.concat([socket.chunck.bufferStack, data]);
    //this is to check if you have a second message incoming 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 completed and/or the incoming 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:"+data.toString()+");
}

弃用警告:“从v10.0.0开始-改用
Buffer.from(string[,encoding])
。”答案很好,我已经找了好几个小时了。这解决了我的“问题”,谢谢!