首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >NodeJS --“套接字挂断”实际上是什么意思?

NodeJS --“套接字挂断”实际上是什么意思?
EN

Stack Overflow用户
提问于 2013-06-08 01:45:25
回答 33查看 744K关注 0票数 397

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

它每次都发生在不同的位置,所以有时是url x抛出错误,另一些时候url x很好,它是一个完全不同的url:

代码语言:javascript
运行
复制
    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错误还是类似的错误?或者这仅仅意味着服务器拒绝连接?

我哪儿都找不到解释!

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

代码语言:javascript
运行
复制
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
    });
}

没有直接调用来关闭连接,但我使用的是Node Request (据我所知)使用http.get,因此这是不需要的,如果我错了,请纠正我!

prodURL编辑2:这是一个实际的、正在使用的代码,它会导致错误,、、和其他变量大多是前面定义的jquery。它将 异步 库用于Node.

代码语言:javascript
运行
复制
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);
                }
            ]);
    });
}
EN

回答 33

Stack Overflow用户

发布于 2015-01-08 07:37:30

在抛出socket hang up时,有两种情况:

当你是客户的时候

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

当您是服务器/代理时

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

此堆栈跟踪显示当客户端取消请求时会发生什么。

代码语言:javascript
运行
复制
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中提到的相同的socketCloseListener,特别是:

代码语言:javascript
运行
复制
// 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套接字,虽然仍然是可写的,但被摧毁。

代码语言:javascript
运行
复制
console.log(res.socket.destroyed); //true

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

代码语言:javascript
运行
复制
res.end();

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

票数 259
EN

Stack Overflow用户

发布于 2013-06-08 01:51:38

看看来源

代码语言:javascript
运行
复制
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;
  }
}

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

票数 62
EN

Stack Overflow用户

发布于 2014-05-13 17:08:34

值得一提的是:在使用Express从Node.js连接到Node.js时,如果不在请求的URL路径前缀加上"/“,就会得到”套接字挂起“。

票数 54
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16995184

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档