当前位置: 首页 > 知识库问答 >
问题:

“套接字挂起”实际上是什么意思?

马淇
2023-03-14

我正在用Node和Cheerio构建一个网络刮刀,对于某个网站,我得到了以下错误(它只发生在这一个网站上,没有其他我试图刮掉的网站)。

它每次都发生在不同的位置,因此有时抛出错误的是url x,而其他时间url x则没有问题,它是一个完全不同的url:

    Error!: Error: socket hang up using [insert random URL, it's different every time]

Error: socket hang up
    at createHangUpError (http.js:1445:15)
    at Socket.socketOnEnd [as onend] (http.js:1541:23)
    at Socket.g (events.js:175:14)
    at Socket.EventEmitter.emit (events.js:117:20)
    at _stream_readable.js:910:16
    at process._tickCallback (node.js:415:13)

这是非常棘手的调试,我真的不知道从哪里开始。首先,什么是套接字挂起错误?这是404错误还是类似的错误?或者这仅仅意味着服务器拒绝了连接?

我在任何地方都找不到解释!

编辑:以下是(有时)返回错误的代码示例

function scrapeNexts(url, oncomplete) {
    request(url, function(err, resp, body) {

        if (err) {
            console.log("Uh-oh, ScrapeNexts Error!: " + err + " using " + url);
            errors.nexts.push(url);
        }
        $ = cheerio.load(body);
        // do stuff with the '$' cheerio content here
    });
}

没有直接调用来关闭连接,但我使用的是节点请求,据我所知,它使用的是http。获取,因此这不是必需的,如果我错了,请纠正我!

编辑2:这里有一个实际的、正在使用的代码位,它会导致错误prodURL和其他变量大多是前面定义的jquery选择器。这将使用节点的async库。

function scrapeNexts(url, oncomplete) {
    request(url, function (err, resp, body) {

        if (err) {
            console.log("Uh-oh, ScrapeNexts Error!: " + err + " using " + url);
            errors.nexts.push(url);
        }
        async.series([
                function (callback) {
                    $ = cheerio.load(body);
                    callback();
                },
                function (callback) {
                    $(prodURL).each(function () {
                        var theHref = $(this).attr('href');
                        urls.push(baseURL + theHref);
                    });
                    var next = $(next_select).first().attr('href');
                    oncomplete(next);
                }
            ]);
    });
}

共有3个答案

雍飞雨
2023-03-14

值得一提的一个案例是:当使用Express从Node.js连接到Node.js时,如果我不将请求的URL路径前缀为"/",我将获得"套接字挂断"。

索寒
2023-03-14

看看来源:

function socketCloseListener() {
  var socket = this;
  var parser = socket.parser;
  var req = socket._httpMessage;
  debug('HTTP socket close');
  req.emit('close');
  if (req.res && req.res.readable) {
    // Socket closed before we emitted 'end' below.
    req.res.emit('aborted');
    var res = req.res;
    res.on('end', function() {
      res.emit('close');
    });
    res.push(null);
  } else if (!req.res && !req._hadError) {
    // This socket error fired before we started to
    // receive a response. The error needs to
    // fire on the request.
    req.emit('error', createHangUpError());
    req._hadError = true;
  }
}

当服务器从未发送响应时,将发出该消息。

冀阳文
2023-03-14

有两种情况下,当套接字挂起被抛出:

当您作为客户端向远程服务器发送请求,但没有收到及时响应时。您的套接字已结束,引发此错误。您应该捕获此错误并决定如何处理它:是否重试请求,将其排队等待以后处理,等等。

当您作为服务器(可能是代理服务器)接收到来自客户端的请求,然后开始对其执行操作(或将请求中继到上游服务器),并且在准备响应之前,客户端决定取消/中止该请求。

此堆栈跟踪显示客户端取消请求时发生的情况。

Trace: { [Error: socket hang up] code: 'ECONNRESET' }
    at ClientRequest.proxyError (your_server_code_error_handler.js:137:15)
    at ClientRequest.emit (events.js:117:20)
    at Socket.socketCloseListener (http.js:1526:9)
    at Socket.emit (events.js:95:17)
    at TCP.close (net.js:465:12)

http.js:1526: 9指向@Blender提到的同一个ocketCloseListener,特别是:

// This socket error fired before we started to
// receive a response. The error needs to
// fire on the request.
req.emit('error', createHangUpError());

...

function createHangUpError() {
  var error = new Error('socket hang up');
  error.code = 'ECONNRESET';
  return error;
}

如果客户端是浏览器中的用户,则这是典型的情况。加载某些资源/页面的请求需要很长时间,用户只需刷新页面即可。这样的操作会导致上一个请求被中止,服务器端会抛出此错误。

由于此错误是由客户端的意愿引起的,因此他们不希望收到任何错误消息。所以,不必把这个错误当作关键。别理它。这是因为在出现这样的错误时,您的客户机侦听的res套接字虽然仍然可写,但已被破坏。

console.log(res.socket.destroyed); //true

因此,除了显式关闭响应对象外,无需发送任何内容:

res.end();

但是,如果您是已将请求中继到上游的代理服务器,您应该确保的是中止您对上游的内部请求,这表明您对响应不感兴趣,这反过来会告诉上游服务器停止昂贵的操作。

 类似资料:
  • 问题内容: 在构建RPM软件包的过程中,我必须指定BuildRoot,以后将在%install中使用它来侵害$ RPM_BUILD_ROOT。我一直认为$ RPM_BUILD_ROOT是RPM执行打包的假安装。然后,在使用RPM软件包进行安装时,它将安装到实际位置。例如: 我认为$ RPM_BUILD_ROOT仅用于打包过程,并且在某些方面,当用户执行“ rpm -ivh package.rpm”

  • 我目前在我的大学学习数据结构课程,在之前的课程中确实做了一些算法分析,但这是我上一门课程中最困难的部分。我们现在正在我的数据结构课程中复习算法分析,所以我要回顾我上一门课程的教科书,看看它在这个问题上说了什么。 在教科书中,它说“对于我们想要分析的每个算法,我们需要定义问题的大小。”在谷歌上搜索时,还不完全清楚“问题大小”到底意味着什么。我试图对问题的大小有一个更具体的定义,这样我就可以在算法中识

  • 问题内容: 我根本不是Java程序员。我尽力不惜一切代价避免使用它,但是(在学校的意义上)我必须在课堂上使用它。老师要求我们使用Socket(),BufferedReader(),PrintWriter()和其他各种东西,包括BufferedReader()的readLine()方法。 基本上,这就是我遇到的问题。该文档明确指出,readLine应该在输入流的末尾返回null,但这不是正在发生的事

  • 我有一个使用activeMQ消息的项目。它运行良好,但有时会遇到挂起的消息卡在队列中。它说1000入队,0出队,1000分派。它还说1000条待处理的消息。 “待定消息”的可能原因是什么?

  • 我正在阅读Kotlin Coroutine并且知道它是基于函数的。但是是什么意思呢? Coroutine或函数挂起? 摘自https://kotlinlang.org/docs/reference/coroutines.html 哪一个被停职了? 摘自https://kotlinlang.org/docs/reference/coroutines.html 为了继续类比,await()可以是一个挂