用Nodejs http.get循环发送请求时遇到的问题

用Nodejs http.get循环发送请求时遇到的问题

var options = {
host: ‘192.168.1.80’,//80是我的本机
port: ‘80’,
};

var req = http.get(options);

用这个方法发送请求时如果发送到自己的本机就会很快而且不会报错,但如果把host地址改成192.168.1.2的服务器地址 就会报错,错误如下: events.js:72 throw er; // Unhandled ‘error’ event ^ Error: Parse Error at Socket.socketOnData (http.js:1584:20) at TCP.onread (net.js:525:27) 不明白是为什么,求指点


5 回复

问题描述

在使用 Node.js 的 http.get 方法循环发送请求时,当请求目标是本地机器(如 192.168.1.80)时,请求可以成功执行且不会报错。然而,当将目标主机改为另一台服务器(如 192.168.1.2)时,请求会失败并抛出一个错误,提示为 Parse Error

原因分析

Parse Error 通常表示 HTTP 响应头或响应体无法被正确解析。这可能是因为服务器返回的数据格式不符合预期,或者服务器返回了一个非标准的 HTTP 状态码。此外,网络延迟、超时设置不当也可能导致此类问题。

示例代码与解决方案

以下是一个改进后的示例代码,该代码中加入了错误处理逻辑,并使用了 async/await 语法来更好地管理异步操作:

const http = require('http');

// 目标主机
const targetHost = '192.168.1.2';
const targetPort = 80;

function sendRequest(host, port) {
    return new Promise((resolve, reject) => {
        const options = {
            hostname: host,
            port: port,
            path: '/',  // 请求路径,可以根据需要修改
            method: 'GET',
        };

        const req = http.get(options, (res) => {
            let data = '';
            res.on('data', (chunk) => {
                data += chunk;
            });
            res.on('end', () => {
                resolve(data);
            });
        });

        req.on('error', (err) => {
            reject(err);
        });

        // 设置超时时间
        req.setTimeout(10000, () => {
            req.destroy();
            reject(new Error('Request timed out'));
        });
    });
}

(async () => {
    try {
        const response = await sendRequest(targetHost, targetPort);
        console.log('Response:', response);
    } catch (error) {
        console.error('Error:', error.message);
    }
})();

关键点解释

  1. 错误处理:通过 .on('error') 事件监听器捕获请求过程中可能出现的任何错误。
  2. 超时设置:使用 req.setTimeout 来设定请求的超时时间,防止请求长时间无响应。
  3. 数据收集:通过监听 data 事件来累积接收到的数据块,最后在 end 事件触发时拼接成完整的响应体。

通过这种方式,可以更稳健地处理 HTTP 请求,并有效避免因网络问题或服务器响应异常导致的错误。


同样问题求问。

短时间大量请求导致的,建议改成一个一个的处理。

看看 agent.maxSockets是否超过了默认的5,代码如下: var agent = http.globalAgent; var options = { host: ‘192.168.1.80’,//80是我的本机 port: ‘80’, };

var req = http.get(options);

req.on(‘error’, function() { console.log('max request sockets: ’ + agent.maxSockets); // 最大连接数默认为5 console.log('current agent.sockets: ’ + agent.sockets[host + ‘:’ + port]); // 当前agent发起的连接数,如果达到5 ,下面的队列会开始排队 console.log('current agent.requests : ’ + agent.requests[host + ‘:’ + port]); // 等待发起request的队列长度 });

当使用 http.get 方法循环发送请求时,可能会遇到一些问题,特别是在网络请求超时或者目标主机无法正确响应的情况下。你提到的错误 Error: Parse Error 通常发生在 HTTP 响应解析过程中出现问题时。

这可能是由于以下几个原因造成的:

  1. 目标服务器响应不规范:如果目标服务器返回的响应不符合 HTTP 协议标准,那么 http.get 在尝试解析响应时可能会失败。
  2. 网络问题:如果目标服务器或网络环境不稳定,可能会导致请求无法正常完成。
  3. 请求超时:默认情况下,http.get 请求有一定的超时时间,如果请求超过了这个时间没有完成,也可能会导致类似的错误。

为了处理这些问题,可以考虑以下几点:

  • 增加超时时间:你可以通过设置请求的超时时间来避免请求因为等待时间过长而失败。
  • 错误处理:确保为请求添加适当的错误处理机制,以便在发生错误时能够妥善处理。
  • 检查目标服务器状态:确保目标服务器能够正常响应 HTTP 请求。

下面是一个简单的示例代码,展示了如何使用 http.get 发送请求,并增加了超时时间和错误处理机制:

const http = require('http');

function sendRequest(url, callback) {
    const options = {
        hostname: url.hostname,
        port: url.port || 80,
        path: url.path,
        method: 'GET'
    };

    const req = http.get(options, (res) => {
        let data = '';

        res.on('data', (chunk) => {
            data += chunk;
        });

        res.on('end', () => {
            callback(null, data);
        });
    }).on('error', (err) => {
        callback(err);
    });

    // 设置请求超时时间
    req.setTimeout(5000, () => {
        req.destroy();
        callback(new Error("Request Timeout"));
    });
}

// 使用示例
sendRequest({hostname: '192.168.1.2'}, (err, data) => {
    if (err) {
        console.error('请求出错:', err.message);
    } else {
        console.log('接收到的数据:', data);
    }
});

这个示例中,我们定义了一个 sendRequest 函数,它接受一个 URL 对象和一个回调函数作为参数。该函数首先创建了一个 HTTP GET 请求,并设置了超时时间为 5 秒。如果请求超时,请求将被销毁并触发错误回调。此外,我们还添加了错误处理逻辑,以确保即使发生错误也能得到妥善处理。

回到顶部