You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js net.socket重复发送旧数据:如何清除套接字残留数据?

问题

我正在用Node.js为一款即将推出的游戏开发服务器,游戏客户端使用GML语言编写。我通过socket.write向客户端发送数据,但不希望新消息中包含之前socket.write写入的字符串。

例如:

socket.write("hello!");

客户端成功收到字符串"hello!"。

但再次调用socket.write时:

socket.write("hello again!");

客户端会收到字符串"hello!hello again!"。请问这是什么原因导致的?能否在再次调用socket.write前清除套接字中的残留信息?

服务器代码:

var net = require("net");
var port = 3000;

var server = net.createServer();

let sockets = [];
playerID = 0; 

server.on("connection",function(socket)
{
    var addr = socket.remoteAddress;
    console.log("New Connection: " + addr);
    sockets.push(socket);
    playerID += 1;
    socket.ID = playerID;
    console.log(socket.ID);
    sockets.forEach((client) => {
        client.write("Player:Connected:" + socket.ID);
        console.log("Player:Connected:" + socket.ID);
    });
    socket.on("data",function(data)
    {
        console.log("data: " + data);
        if (data.includes("Client:Disconnected")) {
            console.log(socket.remoteAddress + " has disconnected");
            const index = sockets.indexOf(socket);
            if (index > -1) { 
                sockets.splice(index, 1); //remove client from socket list 
            }      
            //Notify the other clients of the disconnect event
            sockets.forEach((socket) => {
                socket.write("Player:Disconnected:" + socket.ID);
            });     
        };
    });

    socket.once("closed",function()
    {
        console.log("Player Disconnected: " + addr);
    });
});

server.listen(port,function()
{
    console.log("The Server has been Started on port " + port);
});

我尝试过谷歌搜索该问题但没有结果,查阅文档也未找到相关信息。

解答
  • 原因分析:Node.js的net.Socket基于TCP协议,而TCP是字节流协议,它不会自动为消息划分边界。服务器多次调用socket.write发送的数据,会被TCP合并成连续字节流发送给客户端。如果客户端没有正确处理消息边界,就会把多次发送的数据当成一个完整消息接收,出现拼接情况。这不是服务器套接字有残留信息,是TCP的特性决定的。

  • 解决方法:需要自定义消息边界规则,让客户端能正确拆分每次的消息:

    1. 使用分隔符:每次发送消息时在结尾加特定分隔符(如\n、|),比如服务器发送socket.write("hello!\n");,客户端接收时按分隔符拆分字符串,提取完整的单条消息。
    2. 固定消息长度:在每个消息前加固定长度的头部,标识后续消息的字节长度。比如先发送4字节的长度值,再发送对应长度的消息内容,客户端先读取长度,再读取对应字节数作为完整消息。
    3. 结构化数据格式:使用JSON等格式发送完整数据,客户端接收后解析成对象,推荐配合分隔符使用,避免部分JSON导致解析错误。

不存在“清除套接字残留信息”的操作,TCP套接字不会缓存未发送的残留数据(调用socket.write返回true后,数据已进入发送流程)。问题核心完全在消息边界处理上,和服务器端套接字状态无关。

内容的提问来源于stack exchange,提问作者Stefqnutz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 15:05:19