Socket hang up错误,如何解决?
发布于 8 年前 作者 qq332769043 39049 次浏览 最后一次编辑是 5 年前 来自 问答

一个最简单的Http的Client和Server,Client弹出Socket hang up错误。 TestHttpClient.js:

var http = require('http');
var options = {
  hostname:'10.10.4.143',
  port:8888,
  path:'/',
  method:'GET'
}

var req = http.request(options);
req.write('发给你了!');
console.log('发给你了!');
req.end();
console.log('gg');

1.jpg

TestHttpServer.js:

var http = require('http');

var server = http.createServer(function(req,res){
  if(req.url!=="favicon.ico"){
    console.log('客户端url:'+req.url)
    req.on('data',function(data){
      console.log('服务器接收到数据:'+data);
      res.end();
    });
  }
}).listen(8888);
console.log('程序gg');

2.jpg

这是为什么呢- - server运行在windows主机端 client运行在linux的另外一个机器上 在同一个局域网内。

5 回复

将GET换成POST就成功了!= = why

原因其实也很简单,因为你使用get的话,是不会走到

req.on('data', function (data) {
        console.log('服务器接收到数据:' + data);
        res.end('200');
    });

里面的,所以本次http请求等于没有end数据回去,那么post因为能走到上述分支,所以执行了res.end,也就不会报错,你的代码稍微改下就行了:

var http = require('http');
var server = http.createServer(function (req, res) {
	if (req.url !== 'favicon.ico') {
    	console.log('客户端url:' + req.url, req.method)
    	req.on('data', function (data) {
        	console.log('服务器接收到数据:' + data);
        	res.end('post');
    	});
    	if (req.method.toUpperCase() == 'GET')
        	res.end('get');
	} else {
    	res.end('NOT FOUND');
	}
}).listen(8888);
console.log('程序gg');

这样保证GET请求也能有数据返回

我翻了下Node的源码,可以看到这个错误是由如下的函数抛出的:

function socketOnEnd() {
	var socket = this;
	var req = this._httpMessage;
	var parser = this.parser;
	if (!req.res && !req.socket._hadError) {
		// 如果连接突然断开,但是客户端缺没有收到一个response,需要发布socket hang up的错误
		//createHangUpError()函数即为抛出socket hang up的异常
		req.emit('error', createHangUpError());
		req.socket._hadError = true;
	}
	if (parser) {
		parser.finish();
		freeParser(parser, req, socket);
	}
	socket.destroy();
}

注释里面也说得很清楚了,你写的那个httpServer,很明显,http的处理句柄对于GET请求根本没有返回响应的地方,但是句柄处理结束server就把socket断开了,所以客户端发现tcp连接被断开,但是确没有任何收到来自服务器的任何响应,因为会抛出这个错误,而且你的客户端代码中也没有使用

req.on('error', err=>console.error(err));

进行异常捕获,所以这个错误直接被抛出成Unhandled错误(未处理的异常),导致客户端进程crash; 其实有很多解决办法,一个是我上面写的给GET请求添加进行处理的函数; 另外就是增加error处理的函数,这样抛出异常,客户端也不会挂掉~

回到顶部