Как исправить ошибку: слушать 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);
stewe
источник
1
Я запускаю только этот сервер. До того, как я запускаю сервер, xmlhttprequest работает. После того, как я запускаю сервер на порту 80, сервер также работает отлично. Но если я выполняю xmlhttprequest после запуска сервера, я получаю эту ошибку.
Дэнни Фокс
6
Разве это не выдаст ошибку, если сервер уже прослушивает?
Trysis,
1
Для меня это было вызвано Skype
Beep
559

Что действительно помогло мне:

killall -9 node

Но это убьет системный процесс.

С

ps ax

Вы можете проверить, сработало ли это.

Патрик
источник
1
Также для меня. В моем случае я просто дважды запустил функцию прослушивания и получил ошибку во втором
vabada
2
В соответствующей заметке вы также можете прочитать, когда я не должен убивать процесс .
Nobita
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

Вы можете прочитать немного больше об этом здесь .

РЕДАКТИРОВАТЬ: я читал на довольно смежную тему сегодня и наткнулся на эту интересную ветку о том, почему я не должен kill -9процесс .

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

Итак, как уже говорилось, вам лучше убить описанный выше процесс с помощью:

kill -15 57385

РЕДАКТИРОВАТЬ 2 : Как отмечалось в комментарии здесь много раз, эта ошибка является следствием не изящного выхода из процесса. Это означает, что много людей выйти из команды узла (или любой другой) , используя сочетание клавиш CTRL + Z . Правильный способ остановить запущенный процесс - выполнить команду CTRL + C, которая выполняет чистый выход.

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

Nobita
источник
Где я должен запустить эту команду? В командной строке? На консоли NPM?
Улисс Алвес
@UlyssesAlves просто откройте окно терминала и убейте процесс оттуда.
Нобита
@ Nobita Это работает в Windows? Теперь я понимаю, что это может быть команда MAC OS. Во всяком случае, я перезагрузил свой компьютер и больше не получал эту ошибку. Я думаю, что некоторые другие приложения использовали тот же узел порта, который пытался использовать.
Улисс Алвес
2
pgrep nodeпоказывает, сбежал ли какой-либо процесс узла на вас. pkill nodeубьет их.
Josh.F
3
не для Windows, ребята - вы должны попробовать другой порт или перезагрузить компьютер: P
Tom Stickel
62

Просто голова в голову, Skype иногда прослушивает порт 80 и, следовательно, вызывает эту ошибку, если вы пытаетесь прослушивать порт 80 из Node.js или любого другого приложения.

Вы можете отключить это поведение в Skype, открыв опции и щелкнув Дополнительно -> Соединение -> Использовать порт 80 (снимите этот флажок)

Отключить использование порта 80 Skype

PS После внесения этого изменения не забудьте перезапустить Skype!

Роб Эванс
источник
14
PS После внесения этого изменения не забудьте перезапустить Skype!
Роб Эванс
16
Это один из самых ошеломляющих недостатков дизайна, которые я когда-либо видел. Насколько безумны разработчики Skype, которые они когда-либо рассматривали, принимая 80 или 443?
AJB
5
Большой +1 за ваши навыки отладки, Роб.
AJB
@AJB Они сделали это, чтобы попытаться пробить брандмауэры, которые ограничивают исходящий трафик http-запросами, но там, где брандмауэры не используют DPI, так что просто делайте базовую блокировку портов. Тем не менее ... немного глупо включать это по умолчанию!
Роб Эванс
Да, это пришло мне в голову после небольшого размышления о том, почему они это сделают. Тем не менее, действительно уродливый клудж. И идея о том, что он включен по умолчанию, просто высокомерна.
AJB
39

Вы должны попытаться убить процесс, который прослушивает порт 80.

Killall убьет все работающие приложения узла. Возможно, вы не захотите этого делать. С помощью этой команды вы можете убить только одно приложение, которое прослушивает известный порт.

Если вы используете unix, попробуйте эту команду:

sudo fuser -k 80/tcp    
Яки Кляйн
источник
1
Спасибо Яки. Узел killall для меня не удался, но это сработало.
Пэт М
Спасибо! killall и lsof -i у меня не сработали, но это сработало.
Карфус
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
Wasif
источник
Вы также можете выполнить одну команду в Windows:netstat -ona | findstr ".0:PORT +0.0.0.0:0 +LISTENING" | for /f "tokens=5" %t in ('more') do taskkill /PID:%t /f
З. Кулла,
27

Под контроллером env вы можете использовать:

pkill node перед запуском ваш скрипт должен сделать работу.

Имейте в виду, что эта команда убьет все node процессы, что может быть правильным, если у вас есть, например, контейнер, выполняющий только один экземпляр, а у вас есть такой env, где вы можете это гарантировать.

В любом другом случае я рекомендую использовать команду для уничтожения определенного идентификатора процесса или имени, которое вы нашли, ища его программно. как если бы ваш процесс вызывался, узел-сервер-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
В общем, я говорил на случай, если это был контейнер или очень контролируемое место для процесса.
Хавьер Кобос
Это отличный ответ, я скажу, чем другие, представленные выше. Все, пожалуйста, проголосуйте за это.
Джитендра Павар
@JavierCobos: если вы говорили в пределах контейнера или подобного контролируемого пространства, пожалуйста, добавьте эту информацию к самому ответу. Многие люди не находятся в таких средах, особенно на машине разработки, и это может иметь непредвиденные последствия как таковые. Понижает голосование, но с удовольствием меняет голосование с должным уточнением.
Линдес
1
Многие из них ... но, как человек, который тратит значительную часть времени на подготовку младших разработчиков, и даже вне этого контекста, я могу сказать вам, что очень многие люди используют ответы на Stack Overflow, не понимая, что они делают. ... они просто сталкиваются с проблемой и видят что-то, представленное как решение их проблемы, и они работают с этим. Итак ... Я лично хочу, чтобы сайт давал хорошие объяснения и прививал хорошие общие привычки. Итак, вот откуда я это взял. Я знаю, что это не единственная перспектива. :)
Линдес
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

Это покажет список портов, которые использует ваша система. Найдите, 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]

hientrq
источник
11

EADDRINUSEозначает, что порт (который мы пытаемся прослушать в приложении узла) уже используется. Чтобы преодолеть это, нам нужно определить, какой процесс выполняется с этим портом.

Например, если мы пытаемся прослушать приложение нашего узла в порту 3000. Нам нужно проверить, используется ли этот порт каким-либо другим процессом.

шаг 1:

$sudo netstat -plunt |grep :3000

Что приведенная выше команда дает ниже результат.

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

шаг 2:

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

kill -9 25315

шаг 3:

npm run start

Примечание: это решение для пользователей Linux.

Thavaprakash Swaminathan
источник
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 | grep: 3000

вывод: вы получите информацию о процессе, который использует этот порт

tcp 0 0 IP-адрес: 3000 : СЛУШАТЬ 26869 / узел

Теперь вы можете убить этот процесс sudo kill -9 26869

ВАКАР ШАЙХ
источник
Проверил все ответы. Но вы решаете мою проблему.
Рахул
5

В приведенной ниже команде замените ваш номер порта

sudo lsof -t -i tcp:portNumber | xargs kill -9
Рамачандраредди Реддам
источник
5

EADDRINUSE означает, что порт вашего приложения nodejs уже используется.

  • Теперь вы должны убить процесс / приложение, работающее на этом порту.
  • Найдите идентификатор процесса приложения по:

lsof -i tcp: 3000

  • Теперь вы получите идентификатор процесса из этого.
  • Запустите это:

убить -9 processId

Сидхарт Шривастава
источник
4

Есть способ завершить процесс с помощью диспетчера задач:

Обратите внимание, что это решение только для Windows

  1. Зайдите в диспетчер задач (или воспользуйтесь сочетанием клавиш Ctrl+ Shift+ Esc)

  2. В «Фоновых процессах» найдите процессы «Node.js» и завершите их (щелкните их правой кнопкой мыши и выберите «Завершить задачу»).

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

  1. Теперь вы должны быть в состоянии начать снова
Джи Мок
источник
Для пользователей Mac: 1. Запустите «Монитор активности». 2. Найдите «узел» в строке поиска в правом верхнем углу. 3. Дважды щелкните по процессу узла и выйдите. У вас все настроено!!!! Удачного кодирования.
Апогей
3

Я видел эту ошибку раньше (в узле) с http.client, и, насколько я помню, проблема была связана с не инициализацией httpClient или установкой неверных опций при создании httpClient и / или в запросе url.

ControlAltDel
источник
3

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

node server.js

снова. это работает для меня, некоторое время просто нужно подождать несколько секунд, пока он снова не заработает.

Но это работает только на компьютере разработчика, а не на серверной консоли.

robinclark007
источник
3

Ошибка: прослушивание EADDRINUSE означает, что порт, который вы хотите назначить / привязать к вашему серверу приложений, уже используется. Вы можете назначить другой порт вашему приложению.

Или, если вы хотите назначить тот же порт для приложения. Затем убейте приложение, запущенное на желаемом порту.

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

ps -aux | grep node

После получения идентификатора процесса выполните

kill process_id
Парт Вьяс
источник
тока на windows 10?
Том Стиккель
Нет -aux для систем на основе Linux. Для систем на базе Windows вы можете найти системный монитор для требуемого процесса узла и завершить его.
Парф Вьяс
2

В Debian я обнаружил, что для запуска на 80-м порту необходимо выполнить команду от имени root, т.е.

sudo node app.js

Я надеюсь, что это помогает

Хуррам Ияз
источник
2

В моем случае Apache HTTP Server был запущен на порту 80, я решил это с помощью команды root

sudo killall httpd

Обновить

Если Jenkin установлен и работает на вашем Mac;

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

Кажется, что запущен еще один Node ng обслуживающий процесс. Проверьте это, набрав это в своей консоли (Linux / Mac):

ps aux|grep node

и выйдите из него:

kill -9 <NodeProcessId>

ИЛИ альтернативного использования

ng serve --port <AnotherFreePortNumber>

обслуживать ваш проект на свободном порту по вашему выбору.

Бироль Эфе
источник
1

Убивая NODE_PORT, он может убить ваш процесс chrome или все, что слушает тот же порт, и это раздражает.

Этот сценарий оболочки может быть полезен - в моем случае порт 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 и просто завершить его.

К вашему сведению, я использовал код Visual Studio для запуска Node через порт 3500, и я использую оболочку Git Bash внутри кода VS. Я грациозно завершил работу с помощью Ctrl + C, но иногда это не убивает его. Я не хочу менять свой порт или перезагружаться, чтобы это работало. Надеюсь, это поможет другим. В противном случае это документация для меня.

Том Стиккель
источник
1

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

Stop-Process -processname node
rawel
источник
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
танк Пракаш
источник