Linux平台:CentOS release 6.5 (Final)
Windows平台:Windows 7 旗舰版
服务器端代码如下:
var net = require('net'); var server = net.createServer(function(c){ console.log('client connected: ' + c.remoteAddress); c.setNoDelay(true); c.on('data', function(data){ console.log(data); }); c.on('end', function(){ console.log('disconnected from client'); }); c.on('error', function(err){ console.log(err); }); }); server.listen({port:6200}, function(){ console.log('server bound'); });
客户端代码如下:
const net = require('net'); const client = net.connect({port: 6200, localPort:6201}, function(){ //'connect' listener console.log('connected to server!'); client.setNoDelay(true); for (var i=0; i<1000; i++) { var now = Date.now(); while (Date.now() < now + 3000) {} client.write('中国人'); } }); client.on('data', (data)=>{ console.log(data.toString()); }); client.on('end', ()=>{ console.log('disconnected from server'); });
在Linux上运行server.js,然后分别在Linux上和Winows上执行client.js,并在执行过程中按下Ctrl+C终止进程,我发现服务器端做出的反应是不一样的。当在Linux上终止客户端时,服务器端会输出“disconnected from client”;而在Window上终止客户端时,服务器端会输出“{ [Error: read ECONNRESET] code: 'ECONNRESET', errno: 'ECONNRESET', syscall: 'read' }”(若注释掉服务器端对error事件的监听,则服务器端就会抛出异常并退出)。为什么会这样呢?我用tcpdump工具监听了一下服务器端的6200端口,发现了原因。
//在按下Ctrl+C键时,Linux上的客户端向服务器发送了带FIN标记的报文 16:53:59.948186 IP localhost.6201 > localhost.lm-x: Flags [F.], seq 10, ack 1, win 257, options [nop,nop,TS val 1250056051 ecr 1250053568], length 0
//在按下Ctrl+C键时,在Windows上的“客户端”向服务器发送了带RST标记的报文 16:55:14.681005 IP localhost.6201 > localhost.lm-x: Flags [R.], seq 6007, ack 1, win 0, length 0
注:
1.复位比特(RST):当RST=1时,表明TCP连接中出现严重差错,必须释放连接,再重新建立连接。