如果我强制终止进程然后尝试重新启动它,则 EADDRINUSE 错误

Posted

技术标签:

【中文标题】如果我强制终止进程然后尝试重新启动它,则 EADDRINUSE 错误【英文标题】:EADDRINUSE error if I force kill the process and then try to re-launch it 【发布时间】:2016-09-23 13:51:50 【问题描述】:
var arDrone = require('ar-drone');
var PaVEParser = require('./PaVEParser');
var output = require('fs').createWriteStream('./vid.h264');
var client;
var mostRecentFrame;
var frameCounter = 0;

const net = require('net');
const server = net.createServer((c) => 
  // 'connection' listener
  console.log('client connected');
  c.on('end', () => 
    console.log('client disconnected');
  );
    c.on('data', (data) => 
    c.write(mostRecentFrame);
    );
);
server.on('error', (err) => 
  throw err;
);
server.listen('/tmp/ard.sock', () => 
  console.log('server bound');
);

process.stdin.on('data', function() 
    console.log("Ending the program, landing the drone and terminating the connection.");
    server.close();
    process.exit();
);

当我强制终止该程序时,我无法重新启动它。

daniel@beepboop:~/AR-drone Project$ node test-save-pngs-no-flight.js 
/home/daniel/AR-drone Project/test-save-pngs-no-flight.js:24
  throw err;
  ^

Error: listen EADDRINUSE /tmp/ard.sock
    at Object.exports._errnoException (util.js:1036:11)
    at exports._exceptionWithHostPort (util.js:1059:20)
    at Server._listen2 (net.js:1239:19)
    at listen (net.js:1288:10)
    at Server.listen (net.js:1377:5)
    at Object.<anonymous> (/home/daniel/AR-drone Project/test-save-pngs-no-flight.js:26:8)
    at Module._compile (module.js:556:32)
    at Object.Module._extensions..js (module.js:565:10)
    at Module.load (module.js:473:32)
    at tryModuleLoad (module.js:432:12)

我相信这是因为套接字没有正确关闭。

    当我强行杀死它时,如何让程序关闭套接字,以及 之后如何从命令行手动关闭套接字?

编辑:

我使用的是 Ubuntu 16.04。通过强制终止,我的意思是我在运行时按下“control-C”。

【问题讨论】:

什么操作系统?你是如何强行杀死它的?您是否通过检查系统进程来验证它是否仍在运行?您是否查看过系统报告为打开的套接字? 我不确定如何检查系统进程。控制-C 只是让他们睡觉吗?我添加了其他信息。 您可以使用ps aux查看正在运行的系统进程。您可以通过键入kill xxxx 来终止单个进程,其中xxxx 是您在ps aux 中看到的进程ID。这就是您清理不想再运行的进程的方式。请参阅此处cyberciti.biz/tips/linux-display-open-ports-owner.html,了解如何列出打开的套接字和拥有它们的进程。 @jfriend00 这就是它的工作原理。进程退出时不会删除域套接字,这是设计使然。请参阅我在下面的答案中发布的 GitHub 上问题的链接。 【参考方案1】:

是的,这就是它的工作原理。这是一个更短的例子来重现它:

var net = require('net');
const server = net.createServer((c) => 
);
server.on('error', (err) => 
  throw err;
);
server.listen('/tmp/x.sock', () => 
  console.log('server bound');
);

你可以通过运行来避免这个问题:

server.close();

在程序退出之前。

在您的情况下,您可以通过处理 SIGINT 来避免该问题:

var net = require('net');
const server = net.createServer((c) => 
);
server.on('error', (err) => 
  throw err;
);
server.listen('/tmp/x.sock', () => 
  console.log('server bound');
);
process.on('SIGINT', () => 
  server.close();
  process.exit();
);

另见:

https://github.com/nodejs/node-v0.x-archive/issues/3686 https://github.com/nodejs/node-v0.x-archive/issues/3540

【讨论】:

程序被强制终止时如何触发 server.close()?这可能吗?此外,在我造成此问题后如何解决此问题?我需要重启我的机器吗? @DanielPaczuskiBak 如果“强制终止”是指 Ctrl+C,那么您可以处理 SIGINT 信号 - 您也可以处理 SIGTERM 和其他信号,但您将无法处理 SIGKILL。如果您引起了问题,那么您需要删除/tmp/ard.sock 文件。重新启动系统也应该删除/tmp 中的文件,但您只需要删除文件即可。

以上是关于如果我强制终止进程然后尝试重新启动它,则 EADDRINUSE 错误的主要内容,如果未能解决你的问题,请参考以下文章

批量检测程序无响应

VSPerf 和 A​​zure 云服务

如果找不到则检查进程并重新启动程序的脚本[重复]

如果没有在一小时内结束,请运行一个进程并将其终止

进程被强制终止时的进程退出代码

如何用CMD命令终止和启动进程?