一个最简单的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’);
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’);
这是为什么呢- - server运行在windows主机端 client运行在linux的另外一个机器上 在同一个局域网内。
原因其实也很简单,因为你使用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处理的函数,这样抛出异常,客户端也不会挂掉~