Nodejs不停刷新报socket hang up,求解,是不是和缓冲区有关?

Nodejs不停刷新报socket hang up,求解,是不是和缓冲区有关?

读取一个文件,然后输出输出,一般情况下正常,可是我要是不停地按F5就会有一定几率报 socket hang up 错误,请问是什么问题,是不是要用缓冲区处理?

http.createServer(function(req,res){
	var html=fs.readFileSync('./static/css/base.css');
    res.writeHead(200,{"Content-Type" : "text/html"});
    res.write(html);
    res.end();
    console.log('ok')
    //var pathname = url.parse(req.url).pathname; 
    //router(pathname,req,res);
}).listen(port);

然后不停地刷新,就会报下面的错误

Error: socket hang up
at createHangUpError (http.js:1360:15)
at ServerResponse.OutgoingMessage._writeRaw (http.js:507:26)
at ServerResponse.OutgoingMessage._send (http.js:476:15)
at ServerResponse.OutgoingMessage.end (http.js:887:18)
at Server.<anonymous> (F:\kuaipan\node\zhuwenlong\server.js:14:13)
at Server.EventEmitter.emit (events.js:99:17)
at HTTPParser.parser.onIncoming (http.js:1914:12)
at HTTPParser.parserOnHeadersComplete [as onHeadersComplete] (http.js:111:23)
at Socket.socket.ondata (http.js:1811:22)
at TCP.onread (net.js:404:27)

7 回复

根据你描述的情况,出现 socket hang up 错误通常是由于客户端在服务器准备好响应之前就关闭了连接。这可能发生在频繁刷新页面时,客户端在服务器还未完成数据传输的情况下断开了连接。

从你的代码来看,问题可能出在以下几个方面:

  1. 文件读取同步操作:使用 fs.readFileSync 进行同步文件读取,这会导致阻塞当前线程,如果请求频繁,可能会导致资源不足。
  2. 没有处理错误:你没有处理可能出现的错误,例如文件不存在或读取失败。

为了改进这个问题,我们可以使用异步文件读取,并且添加适当的错误处理逻辑。以下是一个改进后的示例代码:

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

http.createServer((req, res) => {
    fs.readFile('./static/css/base.css', (err, data) => {
        if (err) {
            console.error(err);
            res.writeHead(500, {"Content-Type": "text/plain"});
            res.end("Internal Server Error");
            return;
        }

        res.writeHead(200, {"Content-Type": "text/html"});
        res.write(data);
        res.end();
        console.log('ok');
    });
}).listen(port);

console.log(`Server running at http://localhost:${port}/`);

解释

  1. 异步文件读取:使用 fs.readFile 方法进行异步文件读取,这样不会阻塞当前线程。
  2. 错误处理:在回调函数中检查是否有错误发生,并相应地处理这些错误。
  3. 响应头设置:确保响应头正确设置为 text/html,虽然 base.css 是一个 CSS 文件,但这里假设你需要输出 HTML 内容。

通过这种方式,即使频繁刷新页面,服务器也能更稳定地处理请求,减少因资源不足或连接超时而导致的 socket hang up 错误。


同步读取啊~用异步方法

node版本? 0.8.20之后向已关闭的socket连接写入数据会抛出异常。不断F5的过程中,浏览器客户端确实有可能在发起新请求之前,关闭前一个请求的socket连接,从而导致res的写入失败。

异步也是同样的问题后来我才改成同步测试的 发现还是这样的

之前用的是0.8.20

对了 那我如何在写入之前去判断这个socket已经被关闭了呢?

  1. HEAD请求不应该在header后再发送任何字节,就算0\r\n\r\n也不行,至少http.Server不欢迎这种做法。
  2. req.endres.end后的括号不可省略,否则coffee认为这是属性而不是方法。

PS: generated javascripts would be more appreciated than coffescript.

你遇到的 socket hang up 错误通常与客户端连接超时或网络问题有关。在你提供的代码中,每次请求都同步读取并发送整个文件,这在高并发情况下可能导致服务器无法及时响应,从而导致客户端断开连接。

要解决这个问题,可以考虑使用流式处理(stream)来读取和发送文件,这样可以减少内存占用,并且提高响应速度。以下是修改后的代码示例:

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

http.createServer((req, res) => {
    const fileStream = fs.createReadStream('./static/css/base.css');
    res.writeHead(200, { "Content-Type": "text/html" });
    
    fileStream.pipe(res); // 使用管道将文件流直接发送到响应

    fileStream.on('error', (err) => {
        res.writeHead(500);
        res.end('Internal Server Error');
    });

    res.on('close', () => {
        fileStream.destroy(); // 如果客户端断开连接,关闭文件流
    });

    console.log('ok');
}).listen(port);

解释

  1. 使用 fs.createReadStream():该方法创建了一个可读的文件流,它会逐块读取文件内容。
  2. 使用 pipe() 方法:将文件流直接传输到响应对象上,这样就避免了将整个文件加载到内存中。
  3. 处理错误:通过监听 fileStreamerror 事件来处理可能的文件读取错误。
  4. 处理客户端断开连接:通过监听 res 对象的 close 事件,可以在客户端断开连接时停止读取文件。

这种做法可以显著降低内存使用,并提高服务器处理高并发请求的能力。

回到顶部