Як виправити помилку: слухайте EADDRINUSE під час використання nodejs?


466

Якщо я запускаю сервер з портом 80, і я намагаюся використовувати xmlHTTPrequest, я отримую цю помилку:Error: listen EADDRINUSE

Чому це проблема для nodejs, якщо я хочу зробити запит, коли я запускаю сервер на порту 80? Для веб-браузерів це не проблема: я можу серфінгу в Інтернеті, поки сервер працює.

Сервер:

  net.createServer(function (socket) {
    socket.name = socket.remoteAddress + ":" + socket.remotePort;
    console.log('connection request from: ' + socket.remoteAddress);
    socket.destroy();
  }).listen(options.port);

І запит:

var xhr = new XMLHttpRequest();

xhr.onreadystatechange = function() {
    sys.puts("State: " + this.readyState);

    if (this.readyState == 4) {
        sys.puts("Complete.\nBody length: " + this.responseText.length);
        sys.puts("Body:\n" + this.responseText);
    }
};

xhr.open("GET", "http://mywebsite.com");
xhr.send();

Ви впевнені, що options.port визначено як 80? Чи працює код XHR у браузері? Чи можете ви запустити "nc -l 0.0.0.0 80", коли цей сервер не працює?
Тимофі Мід

Див аналогічне питання на stackoverflow.com/questions/8553957 / ...
Манохар Редді Poreddy

На якій системі ви працюєте? Деякі системи потребують sudo, якщо ви хочете прослуховувати порти нижче певного граничного значення.
Кебман

ця проблема виникає через те, що ви або запустили свій сервер на цьому порту, і ви не закрили цей порт, помилка чітко говорить про те, що порт вже використовується, це відбувається для мене, коли я відкриваю новий проект в коді vs, не закриваючи інші проекти (відкриття перетягуванням)
Ашад Насім

Відповіді:


412

EADDRINUSEозначає, що номер порту, який listen()намагається зв'язати сервер, вже використовується.

Отже, у вашому випадку вже має бути запущений сервер на порту 80.

Якщо на цьому порту працює інший веб-сервер, ви повинні поставити node.js за цим сервером і проксі через нього.

Слід перевірити, чи є така listeningподія, щоб побачити, чи сервер насправді слухає:

var http=require('http');

var server=http.createServer(function(req,res){
    res.end('test');
});

server.on('listening',function(){
    console.log('ok, server is running');
});

server.listen(80);

1
Я запускаю лише цей сервер. Перед запуском сервера працює xmlhttprequest. Після запуску сервера на порту 80, сервер також ідеально працює. Але якщо я запускаю xmlhttprequest після запуску сервера, я отримую цю помилку.
Danny Fox

6
Чи все-таки це не призведе до помилки, якщо сервер вже слухає?
trysis

1
Для мене це спричинило Skype
Beep

559

Що мені справді допомогло:

killall -9 node

Але це вб'є системний процес.

З

ps ax

ви можете перевірити, чи спрацювало воно.


1
Також для мене. У моєму випадку я просто запускаю функцію прослуховування двічі і отримав помилку у другому
vabada

2
У відповідній записці ви також можете прочитати, коли я не повинен вбивати -9 процес .
Нобіта

12
Проблема тут у тому, що ви, хлопці, не виходили з процесу вузла витончено після першого запуску. Тому вузол все ще прив’язаний до цього порту. ps aux | grep nodeпоказало б це. Замість того , щоб вбити додаток з CTRL + Z , вийти з програми з CTRL + C . Це виходить із програми витончено, а прив'язка порту видаляється.
riser101

22
Більше 150 голосів за рішення, яке прирівнюється до посягання на ваше програмне забезпечення за допомогою молотка.
LeeGee

1
Це рішення є досить проблематичним, оскільки прапор -9 вбиває процес, не звільняючи пам'ять. Вам слід використовувати це лише як останнє рішення.
Які Кляйн

279

Вищезазначене killall -9 node, запропоноване Патріком, працює, як очікувалося, і вирішує проблему, але ви можете прочитати редагування цієї самої відповіді про те, чому kill -9це не найкращий спосіб зробити це.

Крім того, ви можете націлити на один процес, а не сліпо вбивати всі активні процеси.

У цьому випадку спочатку знайдіть ідентифікатор процесу (PID) процесу, що працює на цьому порту (скажімо, 8888):

lsof -i tcp:8888

Це поверне щось на кшталт:

COMMAND   PID    USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
node     57385   You   11u  IPv6 0xac745b2749fd2be3      0t0  TCP *:ddi-tcp-1 (LISTEN)

Тоді просто зробіть (ps - насправді цього немає . Будь ласка, читайте нижче):

kill -9 57385

Ви можете прочитати трохи більше про це тут .

EDIT: Я сьогодні читав досить споріднену тему і натрапив на цю цікаву тему про те, чому я не повинен kill -9процес .

Як правило, слід використовувати kill -15 перед kill -9, щоб дати цільовому процесу можливість очиститись після себе. (Процеси не можуть наздогнати або ігнорувати SIGKILL, але вони можуть і часто вловлювати SIGTERM.) Якщо ви не даєте процесу закінчити те, що він робить, і очистити, він може залишити пошкоджені файли (або інший стан) навколо що він не зможе зрозуміти після перезапуску.

Отже, як зазначено, вам слід краще вбити вищезазначений процес за допомогою:

kill -15 57385

EDIT 2 : Як зазначалося в коментарі тут, багато разів ця помилка є наслідком того, що процес не виходить граціозно. Це означає, що багато людей вийти з команди вузла (або будь-який інший) , використовуючи поєднання клавіш CTRL + Z . Правильний спосіб зупинки запущеного процесу - видача CTRL + C яка виконує чистий вихід.

Правильний вихід із процесу звільнить цей порт під час вимкнення. Це дозволить вам перезапустити процес, не переживаючи проблеми вбивства самостійно, перш ніж мати можливість повторно запустити його.


Де мені запустити цю команду? У командному рядку? На консолі NPM?
Улісс Алвес

@UlyssesAlves просто відкрити вікно терміналу і вбити процес звідти.
Нобіта

@Nobita Це працює в Windows? Тепер я розумію, що це може бути команда ОС MAC. У всякому разі, я перезапустив свій комп'ютер і більше не отримував цієї помилки. Я думаю, якийсь інший додаток використовував той самий вузол порту, який намагався використовувати.
Улісс Алвес

2
pgrep nodeпоказує, чи на вас утік який-небудь процес вузла. pkill nodeвб'є їх.
Josh.F

3
не для Windows, люди - вам доведеться спробувати інший порт або перезавантажити комп’ютер: P
Tom Stickel

62

Скайп іноді прослуховує порт 80 і тому спричинить цю помилку, якщо ви спробуєте прослухати порт 80 від Node.js або будь-якого іншого додатка.

Ви можете вимкнути таку поведінку в Skype, відвідавши параметри та натиснувши кнопку Додатково -> З'єднання -> Використовувати порт 80 (Скасувати це)

Вимкніть використання порту Skype 80

PS Після внесення цієї зміни не забудьте перезапустити Skype!


14
PS Після внесення цієї зміни не забудьте перезапустити Skype!
Роб Еванс

16
Це один з найбільш ошатніх недоліків дизайну, який я коли-небудь бачив. Наскільки божевільні скайп-розробки, що вони коли-небудь могли б розглянути питання про взяття 80 чи 443?
AJB

5
Великий +1 для ваших навичок налагодження, Роб.
AJB

@AJB Вони зробили це, щоб спробувати пробити через брандмауери, які обмежують вихідний трафік на запити http, але там, де брандмауери не використовують DPI, тому просто блокують базовий порт. І все-таки ... дещо глупо ввімкнути це за замовчуванням!
Роб Еванс

Так, це мені прийшло в голову після трохи роздуму над тим, чому вони це роблять. І все-таки справді потворна хижака. І думка про те, що це увімкнено за замовчуванням - просто зарозуміла.
AJB

38

Спробуйте вбити процес, який слухається на порту 80.

Killall знищить усі запущені програми вузлів. Можливо, ви не хочете цього робити. За допомогою цієї команди ви можете вбити лише один додаток, який слухає на відомому порту.

Якщо ви використовуєте unix, спробуйте виконати цю команду:

sudo fuser -k 80/tcp    

1
Спасибі Які. killall-вузол для мене не вдався, але це спрацювало.
Пт М

Дякую! killall та lsof -i не працювали для мене, але це було.
karfus

1
Можливо, ви не хочете вбивати всі запущені програми вузлів.
Які Кляйн

28

Причина помилки: Ви намагаєтеся використовувати зайнятеport number

Два можливих рішення для Windows / Mac

  1. Безкоштовно використаний номер порту
  2. Виберіть інший номер порту для вашої поточної програми


1. Безкоштовний номер порту

Windows

1. netstat -ano | findstr :4200
2. taskkill /PID 5824 /F

введіть тут опис зображення

Мак

Ви можете спробувати netstat

netstat -vanp tcp | grep 3000

Для OSX El Capitan та новіших версій (або якщо ваш netstat не підтримує -p), використовуйте lsof

sudo lsof -i tcp:3000

якщо це не вирішує вашу проблему, Macкористувачі можуть звернутися до повного обговорення цієї проблеми. Знайти (і вбити) процес блокування порту 3000 на комп'ютері Mac


2. Змінити номер порту?

Windows

set PORT=5000

Мак

export PORT=5000

Ви також можете виконати одну команду і в Windows:netstat -ona | findstr ".0:PORT +0.0.0.0:0 +LISTENING" | for /f "tokens=5" %t in ('more') do taskkill /PID:%t /f
Z. Khullah

27

Під контролером env ви можете використовувати:

pkill node перед тим, як запустити сценарій, слід виконати цю роботу.

Майте на увазі, що ця команда вб'є всіх node процеси, що може бути правильним, якщо у вас є контейнер, на якому працює лише один екземпляр, у нас у вас є така програма, де ви можете це гарантувати.

У будь-якому іншому випадку я рекомендую використовувати команду, щоб вбити певний ідентифікатор процесу або ім'я, яке ви знайшли, шукаючи його програмно. наприклад, якщо ваш процес викликається, node-server-1 ви могли б зробити pkill node-server-1.

Цей ресурс може бути корисним для розуміння: https://www.thegeekstuff.com/2009/12/4-ways-to-kill-a-process-kill-killall-pkill-xkill/


2
pgrep nodeперед рукою, якщо ви хочете бути трохи обережними і подивитися, які nodeпроцеси працюють
Josh.F

1
Зовсім !, я говорив на випадок, якщо це контейнер або дуже контрольоване місце для процесу.
Хав'єр Кобос

Це скажу приголомшливу відповідь, ніж інші, наведені вище. Усі, будь ласка, підкресліть це.
Jitendra Pawar

@JavierCobos: якщо ви говорили за контейнер або подібний контрольований простір, будь ласка, додайте цю інформацію до самої відповіді. Багато людей не знаходяться в таких умовах, особливо на розробці, і це могло б мати непередбачувані наслідки. Схильний, але радий змінити голосування з належним уточненням.
Лінди

1
Багато хто… але, як хтось витрачає значні шматки часу, допомагаючи навчати молодших розробників, і навіть поза цим контекстом, я можу вам сказати, що дуже багато людей використовують відповіді на Stack Overflow, не розуміючи, що вони роблять. .. вони просто стикаються з проблемою і бачать щось, що представляється як вирішення того, що, здається, є їхньою проблемою, і вони з нею працюють. Отже ... я особисто бажаю, щоб сайт давав хороші пояснення та сприяв розвитку загальних звичок. Отже, ось звідки я з цього приводу. Я знаю, що це не єдина перспектива. :)
lindes

16

Ваша програма вже працює на цьому порту 8080. Використовуйте цей код, щоб вбити порт і запустити його ще раз

sudo lsof -t -i tcp:8080 | xargs kill -9

Питання посилається на порт 80, а не на 8080. Крім того, хоча це, ймовірно, спрацювало б для позбавлення від порушення процесу на порт 8080, використання kill -9майже напевно є надмірним, і, на мою думку, жахливою порадою, яку слід дати без конкретних попереджень про це. Просто kill, мабуть, вдалося б зробити трюк, і дійсно, основна проблема в цьому питанні - я думаю, що вони намагаються заново запускати сервер знову і знову, тому це лише хак, а не виправлення. Вони повинні краще зрозуміти, що відбувається, чого ця відповідь насправді не дає.
Лінди

15

Інша річ, яка може призвести до цієї помилки, це два сервери HTTP в одному і тому ж коді вузла. Я оновлював деякий Express 2 до коду Express 3 і мав це ...

http.createServer(app).listen(app.get('port'), function(){            
  console.log('Express server listening on port ' + app.get('port')); 
});        

// tons of shit.

http.createServer(app).listen(app.get('port'), function(){            
  console.log('Express server listening on port ' + app.get('port')); 
});                                                                   

І це спровокувало цю помилку.


14

Це працює для мене (я використовую mac). Виконайте цю команду

lsof -PiTCP -sTCP:LISTEN

Це відобразить список портів, які використовує ваш syetem. Знайдіть, PIDщо працює ваш вузол

COMMAND     PID          USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
node      17269 hientrq   16u  IPv6 0xc42959c6fa30c3b9      0t0  TCP *:51524 (LISTEN)
node      17269 hientrq   19u  IPv4 0xc42959c71ae86fc1      0t0  TCP localhost:1337 (LISTEN)

і біжи kill -9 [YOUR_PID]


11

EADDRINUSEозначає, що порт (який ми намагаємося прослухати в додатку вузла) вже використовується. Щоб подолати, нам потрібно визначити, який процес працює з цим портом.

Наприклад, якщо ми намагаємося прослухати нашу програму для вузла на 3000 порту. Ми повинні перевірити, чи вже цей порт використовується в будь-якому іншому процесі.

крок 1:

$sudo netstat -plunt |grep :3000

Що наведена вище команда дає нижчий результат.

tcp6       0      0 :::3000                 :::*                    LISTEN      25315/node

крок 2:

Тепер у вас є ідентифікатор процесу (25315), вбити цей процес.

kill -9 25315

step3:

npm run start

Примітка. Це рішення для користувачів Linux.


9
lsof -i:3000;
kill -9 $(lsof -t -i:3000);
// 3000 is a your port
// This "lsof -i:3000;" command will show PID 
kill PID 
ex: kill 129393

3
Додайте більше контексту до своїх відповідей, щоб допомогти майбутнім читачам зрозуміти код / ​​команду.
Міло,

8

sudo kill $ (sudo lsof -t -i: 80)

для вбивства силою

sudo kill -9 $ (sudo lsof -t -i: 80)

використовувати вище cmd, щоб вбити конкретний порт, а потім запустити ваш сервер


8

Спробуйте обидві команди, і це зупинить весь процес вузла.

killall 9 node
pkill node
npm start 

1
цей злом допоміг мені, заощаджую багато часу
Anoop PS

5

Ця помилка виникає, коли у вас працює який-небудь процес на порту, на якому ви хочете запустити свою програму.

як запустити, який процес працює на цьому порту => команда: sudo netstat -ap | греп: 3000

Вихід: ви отримаєте інформацію про процес, який використовує цей порт

tcp 0 0 IP-адреса: 3000 : LISTEN 26869 / вузол

Тепер ви можете вбити цей процес sudo kill -9 26869


Перевірив усі відповіді. Але ти вирішуєш мою проблему.
Рахул


5

EADDRINUSE означає, що порт вашої програми nodejs вже використовується.

  • Тепер ви вбили процес / додаток, що працює на цьому порту.
  • Знайдіть ідентифікатор процесу програми:

lsof -i tcp: 3000

  • Тепер ви отримаєте ідентифікатор процесу від цього.
  • Виконати це:

kill -9 processId


4

Існує спосіб припинити процес за допомогою диспетчера завдань:

Зауважте, що це рішення призначене лише для Windows

  1. Перейдіть до диспетчера завдань (або за допомогою ярлика Ctrl+ Shift+ Esc)

  2. У "Фонових процесах" знайдіть процеси "Node.js" та припиніть їх (клацніть правою кнопкою миші та виберіть "Завершити завдання")

введіть тут опис зображення

  1. Тепер ви повинні мати можливість почати заново

Для користувачів Mac: 1. Запустіть "Монітор активності" 2. Знайдіть "вузол" на панелі пошуку вгорі праворуч. 3. Двічі клацніть процес вузла та вийдіть. Ви все налаштовані !!!! Щасливе кодування.
Апогей

3

Я бачив цю помилку раніше (у вузлі) з http.client, і, як я пам’ятаю, проблема стосувалася не ініціалізації httpClient або встановлення поганих параметрів у створенні httpClient та / або в запиті URL.


3

У мене є та ж проблема, і я просто закриваю термінал і відкриваю новий термінал і запускаю

node server.js

знову. що працює для мене, потрібно трохи зачекати кілька секунд, поки він знову не працює.

Але це працює лише на машині розробника, а не на консолі сервера.


3

Помилка: прослухати EADDRINUSE означає, що порт, який ви хочете призначити / прив’язати до вашого сервера додатків, вже використовується. Ви можете призначити інший порт для вашої програми.

Або якщо ви хочете призначити той же порт для програми. Потім вбити програму, яка працює у потрібному порту.

Для додатка з вузлом ви можете спробувати знайти ідентифікатор процесу для додатка вузла:

ps -aux | grep node

Отримавши ідентифікатор процесу, зробіть

kill process_id

-aux на windows 10?
Том Стікель

No -aux не застосовується для систем на базі Linux. Для систем на основі Windows ви можете знайти монітор системи для потрібного процесу вузла і закінчити його.
Парф Вяс

2

На Debian я виявив, що для запуску на порт 80 вам потрібно випустити команду як root, тобто

sudo node app.js

Я сподіваюся, що це допомагає


2

У моєму випадку Apache HTTP Server запускався на порт 80, я вирішив його, видавши команду як root

sudo killall httpd

Оновлення

Якщо Дженкін встановлений і працює на вашому Mac;

  1. Ви можете це перевірити sudo lsof -i tcp:8080
  2. Якщо так, і ви хочете зупинити Дженкінса лише один раз, запустіть: sudo launchctl unload /Library/LaunchDaemons/org.jenkins-ci.plist

2

Здається, працює ще один процес обслуговування сервісного вузла. Перевірте це, ввівши це у консолі (Linux / Mac):

ps aux|grep node

і киньте його:

kill -9 <NodeProcessId>

АБО альтернативне використання

ng serve --port <AnotherFreePortNumber>

щоб обслуговувати ваш проект у вільному виборі порту.


1

Убиваючи NODE_PORT, це може вбити ваш хромований процес або все, що слухає той же порт, і це дратує.

Цей скрипт оболонки може бути корисним - у моєму випадку порт 1337, але його можна змінити будь-коли

# LOGIC

CHROME_PIDS=`pidof chrome`
PORT_PIDS=`lsof -t -i tcp:1337`

for pid in $PORT_PIDS
do

if [[ ${CHROME_PIDS} != *$pid* ]];then

    # NOT FOUND IN CHROME PIDS

    echo "Killing $pid..."
    ps -p "$pid"

    kill -kill "$pid"
    fi

done

sails lift
# OR 'node app' OR whatever that starts your node

exit

1

У моєму випадку я використовую веб-хостинг, але це так само в локальному хості, я використовував:

ps -aef | grep 'node' 

щоб потім спостерігати процес вузла, консоль показує процес з PID. для вбивства процесу ви повинні використовувати цю команду:

kill -9 PID

де PID - ідентифікатор процесу з команди вище.


1

Два сервери не можуть прослуховувати на одному порту, тому перевірте, чи слухає інший сервер на тому самому порту, також перевіряйте синхронізацію браузера, якщо його працює на тому ж порту


1

Для інших людей на Windows 10 з вузлом як localhostі працює на порт, як 3500, а не 80 ...

Що не працює:

killall    ?  command not found
ps -aux | grep 'node'     ?     ps:  user x unknown 

Що показує інформацію, але все ще не працює:

 ps -aef | grep 'node'
 ps ax
 kill -9 61864

Що працює:

Git Bash або Powershell на Windows

  net -a -o | grep 3500   (whatever port you are looking for) 

Зауважте PID (вкрай праворуч),
я не міг дійти killallдо роботи ... так

  1. Відкрийте менеджер завдань
  2. На вкладці "Процеси" клацніть правою кнопкою миші Ім'я або будь-який стовпець і виберіть для включення PID
  3. Сортування за PID, потім клацніть правою кнопкою миші правою PID та натисніть кінцеве завдання.

Тепер після цієї не дуже цікавої вправи на windows, я зрозумів, що можу використовувати диспетчер завдань і знайти двигун Node і просто закінчити його.

FYI, я використовував Visual Studio Code, щоб запустити Node на порт 3500, і я використовую оболонку Git Bash всередині коду VS. Я вишукано вийшов із Ctrl + C, але іноді це не вбиває. Я не хочу змінювати порт або перезавантажувати, щоб це спрацювало. Сподіваємось, це допомагає іншим. Інакше це документація для мене.


1

Для Windows користувачі виконують наступну команду у вікні PowerShell, щоб знищити всі вузлові процеси.

Stop-Process -processname node

1

Варіант, який працює для мене:

Виконати:

ps -ax | grep node

У вас вийде щось на кшталт:

 8078 pts/7    Tl     0:01 node server.js
 8489 pts/10   S+     0:00 grep --color=auto node    
 kill -9 8078
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.