Nodejs 求助:获取大量数据并存储本地时出错 Error: socket hang up

Nodejs 求助:获取大量数据并存储本地时出错 Error: socket hang up

求助:错误代码如下:

events.js:72
        throw er; // Unhandled 'error' event
              ^
Error: socket hang up
    at createHangUpError (http.js:1472:15)
    at Socket.socketOnEnd [as onend] (http.js:1568:23)
    at Socket.g (events.js:180:16)
    at Socket.EventEmitter.emit (events.js:117:20)
    at _stream_readable.js:919:16
    at process._tickCallback (node.js:419:13)

5 回复

Node.js 求助:获取大量数据并存储本地时出错 Error: socket hang up

问题描述

当你尝试从网络上获取大量数据并将其存储到本地文件时,可能会遇到一个错误信息 Error: socket hang up。这个错误通常发生在HTTP请求过程中,表示连接被服务器提前关闭了。

可能的原因

  1. 网络问题:可能由于网络不稳定导致请求中断。
  2. 超时设置:请求可能因为超时而被终止。
  3. 服务器限制:服务器可能限制了长时间的请求或大流量的请求。

解决方案

可以通过以下几种方式来解决这个问题:

  1. 增加超时时间:通过设置更大的超时时间来避免请求过早结束。
  2. 使用流式处理:使用流式处理来逐步读取和写入数据,而不是一次性加载所有数据到内存中。
  3. 错误处理:确保在请求过程中正确地捕获和处理错误。

示例代码

const http = require('http');
const fs = require('fs');

// 创建请求对象
const options = {
  hostname: 'example.com',
  port: 80,
  path: '/large-data',
  method: 'GET',
  timeout: 60000, // 设置超时时间为60秒
};

// 创建请求
const req = http.request(options, (res) => {
  const fileStream = fs.createWriteStream('data.txt');

  res.pipe(fileStream);

  fileStream.on('finish', () => {
    console.log('Data saved successfully.');
  });

  fileStream.on('error', (err) => {
    console.error('Error saving data:', err);
  });
});

req.on('error', (err) => {
  console.error('Request error:', err);
});

req.end();

代码解释

  1. 创建请求对象

    • 使用 http.request 方法创建一个 HTTP GET 请求。
    • 设置 timeout 属性以延长超时时间。
  2. 响应处理

    • 使用 res.pipe(fileStream) 将响应流直接管道到文件流,这样可以逐块处理数据,避免内存溢出。
    • 监听 finish 事件来确认数据已成功写入文件。
    • 监听 error 事件来处理文件写入过程中的任何错误。
  3. 错误处理

    • 监听 error 事件来捕获请求过程中的错误。

通过这些方法,你可以更稳健地处理大量数据的下载和存储。


检查下获取时是不是出现了错误

少量请求并存储本地,没有问题,但是大量(几千个下载文件到磁盘)就会出这个异常。

我也遇到了这个问题,请问楼主解决了吗?

根据你的描述,出现 “Error: socket hang up” 错误通常表示网络连接在某些情况下被断开了。这可能是由于请求超时、服务器端问题或其他网络不稳定因素导致的。

在这种情况下,可以考虑使用 axiosnode-fetch 这样的库来处理 HTTP 请求,并且增加重试机制以应对临时的网络故障。

以下是一个使用 axios 的示例代码,其中包括了重试机制:

const axios = require('axios');
const pRetry = require('p-retry');

async function fetchData(url) {
    try {
        const response = await pRetry(() => axios.get(url), {
            retries: 3, // 尝试重试3次
            factor: 1,
            minTimeout: 1 * 1000,
            maxTimeout: 60 * 1000,
        });
        return response.data;
    } catch (err) {
        console.error(`请求失败: ${err.message}`);
    }
}

(async () => {
    const url = 'https://example.com/large-data';
    const data = await fetchData(url);

    if (data) {
        // 存储数据到本地文件
        require('fs').writeFileSync('./data.json', JSON.stringify(data));
        console.log('数据已成功保存到本地文件');
    }
})();

在这个例子中:

  • 使用 axios 发起 HTTP GET 请求。
  • 使用 p-retry 库实现重试机制,当遇到 socket hang up 错误时会自动重试。
  • 成功获取数据后,将数据写入本地文件。

如果不想引入额外的依赖,也可以直接在原生 Node.js 中处理重试逻辑。如果只是偶尔遇到这个问题,可能还需要检查一下请求的数据量或服务端的响应时间是否合理。

回到顶部