Nodejs的net模块出现这个问题怎么回事,各位大神帮忙看一下

Nodejs的net模块出现这个问题怎么回事,各位大神帮忙看一下

events.js:72
throw er; // Unhandled ‘error’ event
^

Error: This socket has been ended by the other party at Socket.writeAfterFIN [as write] (net.js:274:12) at broadcast (C:\nodejs\app.js:19:15) at Socket.<anonymous> (C:\nodejs\app.js:60:5) at Socket.EventEmitter.emit (events.js:95:17) at Socket.<anonymous> (stream_readable.js:710:14) at Socket.EventEmitter.emit (events.js:92:17) at emitReadable (_stream_readable.js:382:10) at emitReadable (_stream_readable.js:378:5) at readableAddChunk (_stream_readable.js:143:7) at Socket.Readable.push (_stream_readable.js:113:10)


6 回复

Node.js 的 net 模块出现这个问题怎么回事

你遇到的错误是由于在 Node.js 中使用 net 模块时,一个已经关闭的连接被尝试写入数据。这种错误通常发生在客户端或服务端已经断开连接的情况下,但另一方仍然尝试发送数据。

示例代码及解释

假设我们有一个简单的聊天服务器和客户端应用,其中服务器接收消息并广播给所有已连接的客户端。以下是一个简化版本的代码示例:

const net = require('net');

// 创建一个服务器
const server = net.createServer((socket) => {
    console.log('New client connected');

    // 接收消息并广播
    socket.on('data', (data) => {
        broadcast(data, socket);
    });

    // 当客户端断开连接时清理资源
    socket.on('end', () => {
        console.log('Client disconnected');
    });
});

function broadcast(message, sender) {
    server.connections.forEach((client) => {
        if (client !== sender && client.writable) {
            client.write(message);
        }
    });
}

server.listen(3000, () => {
    console.log('Server listening on port 3000');
});

问题分析

在上面的代码中,如果某个客户端已经断开连接(即 socket.end 被触发),但仍在 broadcast 函数中尝试向该客户端发送消息,就会引发 "This socket has been ended by the other party" 错误。

解决方法

确保在向客户端发送消息之前检查其是否仍然可写:

function broadcast(message, sender) {
    server.connections.forEach((client) => {
        if (client !== sender && client.writable) { // 添加对 writable 的检查
            client.write(message);
        }
    });
}

进一步优化

可以考虑在客户端断开连接时从连接列表中移除该客户端,以避免不必要的错误和资源浪费:

const connections = [];

const server = net.createServer((socket) => {
    connections.push(socket);

    socket.on('end', () => {
        console.log('Client disconnected');
        const index = connections.indexOf(socket);
        if (index > -1) {
            connections.splice(index, 1);
        }
    });

    socket.on('data', (data) => {
        broadcast(data, socket);
    });
});

function broadcast(message, sender) {
    connections.forEach((client) => {
        if (client !== sender && client.writable) {
            client.write(message);
        }
    });
}

server.listen(3000, () => {
    console.log('Server listening on port 3000');
});

通过这些修改,你可以有效地避免因尝试向已断开连接的客户端发送数据而引起的错误。


这不是提示socket 被结束了么

我是在刷新页面的时候,断开重连,断开的时候socket肯定会结束,该怎么解决呢?

监听err,然后重连试试。

多谢两位,找到原因了,延时发送造成的,结束了延时发送就找不到socket了,感谢回答!

从错误日志来看,问题出在 Socket.writeAfterFIN,即尝试在一个已经被另一方结束的连接上进行写操作。这种情况通常发生在客户端或服务端的连接已经断开,但一方仍在尝试向对方发送数据。

示例代码中可能有类似这样的逻辑:

// 假设这是服务器端代码
const net = require('net');
const server = net.createServer(socket => {
    socket.on('data', data => {
        // 向所有连接的socket广播数据
        broadcast(data, socket);
    });
});

function broadcast(data, sender) {
    server.connections.forEach(s => {
        if (s !== sender) {
            s.write(data); // 如果sender的连接已经断开,这将抛出错误
        }
    });
}

server.listen(8000);

解决方案

在发送数据之前,检查连接是否仍然有效:

function broadcast(data, sender) {
    server.connections.forEach(s => {
        if (s !== sender && !s.destroyed && s.writable) { // 检查socket是否已关闭
            s.write(data);
        }
    });
}

另一种解决方案是监听 error 事件

确保你处理了所有的 error 事件,这样可以避免未捕获的异常导致程序崩溃。

socket.on('error', err => {
    console.error('Socket error:', err);
});

以上就是在Node.js中使用 net 模块时遇到 This socket has been ended by the other party 错误的原因及解决方法。

回到顶部