Jak naprawić błąd: Listen EADDRINUSE podczas korzystania z nodejs?


466

Jeśli uruchomię serwer z portem 80 i spróbuję użyć polecenia xmlHTTP, otrzymuję ten błąd:Error: listen EADDRINUSE

Dlaczego jest to problem dla nodejs, jeśli chcę zrobić żądanie, gdy uruchamiam serwer na porcie 80? Dla przeglądarek internetowych to nie problem: mogę surfować po Internecie, gdy serwer jest uruchomiony.

Serwer to:

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

I prośba:

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();

Czy jesteś pewien, że options.port jest zdefiniowany jako 80? Czy kod XHR działa w przeglądarce? Czy można uruchomić „nc -l 0.0.0.0 80”, gdy ten serwer nie działa?
Timothy Meade


Na jakim systemie jesteś? Niektóre systemy wymagają sudo, jeśli chcesz słuchać portów poniżej określonego progu.
Kebman

ten problem powstaje, ponieważ albo uruchomiłeś serwer na tym porcie i nie zamknąłeś tego portu, błąd wyraźnie wskazuje, że port jest już w użyciu, to zdarza mi się, gdy otwieram nowy projekt w kodzie vs bez zamykania innych projektów (otwieranie przeciągnij i upuść)
Ashad Nasim

Odpowiedzi:


412

EADDRINUSEoznacza, że ​​numer portu, który listen()próbuje powiązać serwer, jest już w użyciu.

Tak więc, w twoim przypadku, musi być już uruchomiony serwer na porcie 80.

Jeśli masz inny serwer WWW działający na tym porcie, musisz umieścić node.js za tym serwerem i przez niego proxy.

Powinieneś sprawdzić takie listeningzdarzenie, aby zobaczyć, czy serwer naprawdę nasłuchuje:

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
Prowadzę tylko ten serwer. Przed uruchomieniem serwera xmlhttprequest działa. Po uruchomieniu serwera na porcie 80 serwer działa również doskonale. Ale jeśli zrobię xmlhttprequest po uruchomieniu serwera, to otrzymam ten błąd.
Danny Fox

6
Czy to nadal nie spowoduje błędu, jeśli serwer już nasłuchuje?
trysis

1
Dla mnie było to spowodowane przez Skype
Beep

559

To, co naprawdę mi pomogło, to:

killall -9 node

Ale to zabije proces systemowy.

Z

ps ax

możesz sprawdzić, czy zadziałało.


1
Również dla mnie W moim przypadku po prostu uruchomiłem funkcję
Listen

2
W powiązanej notatce możesz także przeczytać, kiedy nie powinienem kil-9 procesu .
Nobita,

12
Problem polega na tym, że po pierwszym uruchomieniu nie wychodzicie z procesu węzła z wdziękiem. Dlatego węzeł jest nadal powiązany z tym portem. ps aux | grep nodepokaże to. Zamiast zabijać aplikację z Ctrl + Z , zamknąć aplikację z Ctrl + C . Spowoduje to zamknięcie aplikacji z wdziękiem i powiązanie portu zostanie usunięte.
riser101

22
Ponad 150 głosów za rozwiązaniem, które oznacza uderzenie w oprogramowanie młotkiem.
LeeGee

1
To rozwiązanie jest dość problematyczne, ponieważ flaga -9 zabije proces bez zwalniania pamięci. Powinieneś naprawdę użyć tego tylko jako ostatniego rozwiązania.
Yaki Klein

279

Wyżej wspomniane killall -9 node, sugerowane przez Patricka, działa zgodnie z oczekiwaniami i rozwiązuje problem, ale możesz przeczytać część edycyjną tej odpowiedzi na pytanie, dlaczegokill -9 może nie być najlepszym sposobem na zrobienie tego.

Ponadto możesz kierować jeden proces, a nie ślepo zabijać wszystkich aktywne procesy.

W takim przypadku najpierw uzyskaj identyfikator procesu (PID) procesu uruchomionego na tym porcie (powiedzmy 8888):

lsof -i tcp:8888

Zwróci to coś w rodzaju:

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

Następnie po prostu zrób (ps - właściwie nie . Proszę czytaj dalej poniżej):

kill -9 57385

Możesz przeczytać więcej na ten temat tutaj .

EDYCJA: Czytałem dziś dość pokrewny temat i natknąłem się na ten interesujący wątek, dlaczego nie powinienem być kill -9procesem .

Ogólnie rzecz biorąc, powinieneś użyć kill -15 przed kill -9, aby proces docelowy miał szansę oczyścić się po sobie. (Procesy nie mogą złapać ani zignorować SIGKILL, ale mogą i często łapią SIGTERM.) Jeśli nie dasz temu procesowi szansy na ukończenie tego, co robi i wyczyszczenia, może pozostawić uszkodzone pliki (lub inny stan) w pobliżu którego nie będzie w stanie zrozumieć po ponownym uruchomieniu.

Jak już wspomniano, lepiej zabić powyższy proces za pomocą:

kill -15 57385

EDYCJA 2 : Jak zauważono w komentarzu tutaj wielokrotnie, ten błąd jest konsekwencją nie opuszczenia procesu z gracją. Oznacza to, że wiele osób zakończyć polecenie węzła (lub innych) za pomocą CTRL + Z . Prawidłowym sposobem zatrzymania uruchomionego procesu jest wydanie polecenia CTRL + C, które wykonuje czyste wyjście.

Właściwe wyjście z procesu zwolni ten port podczas zamykania. Pozwoli to na ponowne uruchomienie procesu bez kłopotania się z jego zabiciem, zanim będzie można go ponownie uruchomić.


Gdzie mam uruchomić to polecenie? W wierszu polecenia? Na konsoli NPM?
Ulysses Alves

@UlyssesAlves po prostu otwórz okno terminala i stamtąd zabij proces.
Nobita,

@Nobita Czy to działa w systemie Windows? Teraz zdaję sobie sprawę, że może to być polecenie systemu Mac OS. Zresztą zrestartowałem komputer i nie otrzymałem już tego błędu. Myślę, że inna aplikacja używała tego samego węzła portu, którego próbowała użyć.
Ulysses Alves

2
pgrep nodepokazuje, czy jakikolwiek proces węzłowy uciekł. pkill nodezabije ich.
Josh.F

3
nie dla systemu Windows, ludzie - musisz wypróbować inny port lub uruchomić ponownie komputer: P
Tom Stickel

62

Tylko głowa do góry, Skype czasami nasłuchuje na porcie 80 i dlatego powoduje ten błąd, jeśli spróbujesz nasłuchiwać na porcie 80 z Node.js lub innej aplikacji.

Możesz wyłączyć to zachowanie w Skype, otwierając opcje i klikając Zaawansowane -> Połączenie -> Użyj portu 80 (Odznacz to)

Wyłącz użycie portu 80 przez Skype

PS Po wprowadzeniu tej zmiany nie zapomnij ponownie uruchomić Skype!


14
PS Po wprowadzeniu tej zmiany nie zapomnij ponownie uruchomić Skype!
Rob Evans,

16
To jedna z najbardziej oszałamiających wad projektowych, jakie kiedykolwiek widziałem. Jak szaleni są deweloperzy Skype, że kiedykolwiek rozważaliby przejęcie 80 lub 443?
AJB,

5
Duży +1 za twoje umiejętności debugowania, Rob.
AJB,

@AJB Zrobili to, aby spróbować przebić się przez zapory ogniowe, które ograniczają ruch wychodzący do żądań HTTP, ale tam, gdzie zapory ogniowe nie używają DPI, więc po prostu wykonaj podstawowe blokowanie portów. Mimo to ... głupio jest włączyć to domyślnie!
Rob Evans

Tak, przyszło mi do głowy po krótkiej refleksji, dlaczego mieliby to zrobić. Mimo to naprawdę brzydka kludge. Pomysł, że jest domyślnie włączony, jest po prostu arogancki.
AJB

38

Powinieneś spróbować zabić proces nasłuchujący na porcie 80.

Killall zabije wszystkie uruchomione aplikacje węzłów. Możesz tego nie chcieć. Za pomocą tego polecenia możesz zabić tylko jedną aplikację, która nasłuchuje na znanym porcie.

Jeśli używasz Uniksa, wypróbuj to polecenie:

sudo fuser -k 80/tcp    

1
Dzięki Yaki. węzeł killall zawiódł dla mnie, ale to zadziałało.
Pat M

Dzięki! killall i lsof -i nie działały dla mnie, ale to zadziałało.
karfus

1
Możesz nie chcieć zabijać wszystkich uruchomionych aplikacji węzłów.
Yaki Klein,

28

Przyczyna błędu: Próbujesz użyć zajętegoport number

Dwa możliwe rozwiązania dla Windows / Mac

  1. Bezpłatny aktualnie używany numer portu
  2. Wybierz inny numer portu dla bieżącego programu


1. Darmowy numer portu

Windows

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

wprowadź opis zdjęcia tutaj

Prochowiec

Możesz spróbować netstat

netstat -vanp tcp | grep 3000

Dla OSX El Capitan i nowszych (lub jeśli twój netstat nie obsługuje -p), użyj lsof

sudo lsof -i tcp:3000

jeśli to nie rozwiąże problemu, Macużytkownicy mogą zapoznać się z pełną dyskusją na ten temat Znajdź (i zabij) proces blokowania portu 3000 na komputerze Mac


2. Zmienić numer portu?

Windows

set PORT=5000

Prochowiec

export PORT=5000

możesz także wykonać jedno polecenie w netstat -ona | findstr ".0:PORT +0.0.0.0:0 +LISTENING" | for /f "tokens=5" %t in ('more') do taskkill /PID:%t /f
systemie

27

Pod env kontrolera możesz użyć:

pkill node przed uruchomieniem skryptu należy wykonać zadanie.

Pamiętaj, że to polecenie zabije wszystkie node procesy, co może być słuszne, jeśli masz np. Kontener z tylko jedną instancją, a my masz taką env, w której możesz to zagwarantować.

W każdym innym scenariuszu zalecam użycie polecenia, aby zabić określony identyfikator procesu lub nazwę, którą znalazłeś, szukając go programowo. na przykład jeśli twój proces jest nazywany, węzeł-serwer-1 możesz zrobić pkill node-server-1.

Ten zasób może być przydatny do zrozumienia: https://www.thegeekstuff.com/2009/12/4-ways-to-kill-a-process-kill-killall-pkill-xkill/


2
pgrep nodeprzed ręką, jeśli chcesz być trochę ostrożny i zobaczyć, jakie nodeprocesy są uruchomione
Josh.F 27.04.16

1
Całkowicie !, mówiłem na wypadek, gdyby był to pojemnik lub bardzo kontrolowane miejsce dla procesu.
Javier Cobos

To wspaniała odpowiedź powiem niż inne podane powyżej. Proszę, głosujcie za tym.
Jitendra Pawar

@JavierCobos: jeśli występowałeś w kontenerze lub w podobnej kontrolowanej przestrzeni, dodaj tę informację do samej odpowiedzi. Wiele osób nie znajduje się w takich środowiskach, szczególnie na komputerze deweloperskim, co może mieć niezamierzone konsekwencje w obecnej postaci. Głosowanie negatywne, ale chętnie zmienię głosowanie z odpowiednim wyjaśnieniem.
Lindes

1
Wielu będzie ... ale jako ktoś, kto poświęca znaczną część czasu na szkolenie młodszych programistów, a nawet poza tym kontekstem, mogę powiedzieć, że bardzo wiele osób korzysta z odpowiedzi na Stack Overflow, nie rozumiejąc, co robią. .. po prostu mają problem i widzą coś przedstawionego jako rozwiązanie tego, co wydaje się być ich problemem, i biegną z tym. Więc ... Osobiście pragnę, aby strona zawierała dobre wyjaśnienia i pielęgnowała dobre ogólne nawyki. Stąd pochodzę. Wiem jednak, że to nie jedyna perspektywa. :)
Lindes,

16

Twoja aplikacja działa już na tym porcie 8080. Użyj tego kodu, aby zabić port i ponownie uruchomić kod

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

Pytanie dotyczy portu 80, a nie 8080. Ponadto, chociaż prawdopodobnie zadziałałoby to, aby pozbyć się uciążliwego procesu na porcie 8080, korzystanie z niego kill -9jest prawie na pewno przesadzone i, moim zdaniem, okropna rada, której można udzielić bez konkretnych ostrzeżeń o to. Wystarczy killprawdopodobnie rade, a tak naprawdę, podstawowym problemem w tej kwestii jest, jak sądzę, że próbują, aby ponownie uruchomić serwer w kółko, więc jest to tylko hack, a nie dylemat. Muszą lepiej zrozumieć, co się dzieje, czego tak naprawdę nie zapewnia ta odpowiedź.
Lindes

15

Inną rzeczą, która może powodować ten błąd, są dwa serwery HTTP w tym samym kodzie węzła. Zaktualizowałem trochę kodu Express 2 do Express 3 i miałem to ...

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')); 
});                                                                   

I spowodował ten błąd.


14

To działa dla mnie (używam Maca). Uruchom to polecenie

lsof -PiTCP -sTCP:LISTEN

Spowoduje to wyświetlenie listy portów używanych przez twój system. Znajdź PIDdziałający węzeł

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)

i biegnij kill -9 [YOUR_PID]


11

EADDRINUSEoznacza, że ​​port (który próbujemy nasłuchiwać w aplikacji węzła) jest już używany. Aby temu zaradzić, musimy określić, który proces działa z tym portem.

Na przykład, jeśli próbujemy nasłuchiwać aplikacji węzła w porcie 3000. Musimy sprawdzić, czy ten port jest już używany przez inny proces.

krok 1:

$sudo netstat -plunt |grep :3000

Że powyższe polecenie daje wynik poniżej.

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

krok 2:

Teraz masz identyfikator procesu (25315), Zabij ten proces.

kill -9 25315

krok 3:

npm run start

Uwaga: To rozwiązanie dla użytkowników Linuksa.


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
Dodaj więcej kontekstu do swoich odpowiedzi, aby pomóc przyszłym czytelnikom zrozumieć kod / polecenie.
Milo,

8

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

za zabicie siłą

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

użyj powyżej cmd, aby zabić określony port, a następnie uruchom serwer


8

Spróbuj obu poleceń, a zatrzyma cały proces węzła.

killall 9 node
pkill node
npm start 

1
ten hack pomógł mi zaoszczędzić dużo czasu dzięki
Anoop PS

5

Ten błąd pojawia się, gdy na porcie, na którym chcesz uruchomić aplikację, działa dowolny proces.

jak uzyskać, który proces działa na tym porcie => polecenie: sudo netstat -ap | grep: 3000

wyjście: otrzymasz informacje o procesie, który używa tego portu

tcp 0 0 Adres IP: 3000 : Adres IP LISTEN 26869 / node

Teraz możesz zabić ten proces sudo kill -9 26869


Sprawdziłem wszystkie odpowiedzi. Ale rozwiązujesz mój problem.
Rahul


5

EADDRINUSE oznacza, że ​​port Twojej aplikacji nodejs jest już w użyciu.

  • Teraz zabiłeś proces / aplikację działającą na tym porcie.
  • Znajdź identyfikator procesu aplikacji przez:

lsof -i tcp: 3000

  • Teraz otrzymasz z tego identyfikator procesu.
  • Uruchomić to:

kill -9 processId


4

Istnieje sposób na zakończenie procesu za pomocą Menedżera zadań:

Pamiętaj, że to rozwiązanie dotyczy tylko systemu Windows

  1. Przejdź do Menedżera zadań (lub użyj skrótu Ctrl+ Shift+ Esc)

  2. W „Procesach w tle” znajdź procesy „Node.js” i zakończ je (kliknij je prawym przyciskiem myszy i wybierz „Zakończ zadanie”)

wprowadź opis zdjęcia tutaj

  1. Teraz powinieneś móc zacząć od nowa

Użytkownicy komputerów Mac: 1. Uruchom „Monitor aktywności” 2. Wyszukaj „węzeł” na pasku wyszukiwania w prawym górnym rogu. 3. Kliknij dwukrotnie proces węzła i wyjdź. Wszystko gotowe !!!! Szczęśliwego kodowania.
Apogee

3

Widziałem ten błąd wcześniej (w węźle) w http.client i, jak pamiętam, problem dotyczył braku inicjowania httpClient lub ustawiania złych opcji w tworzeniu httpClient i / lub w żądaniu adresu URL.


3

Mam również ten sam problem, po prostu zamykam terminal, otwieram nowy terminal i uruchamiam

node server.js

jeszcze raz. to działa dla mnie, trochę czasu wystarczy poczekać kilka sekund, aż znowu zadziała.

Ale działa to tylko na komputerze dewelopera zamiast na konsoli serwera.


3

Błąd: Listen EADDRINUSE oznacza, że ​​port, który chcesz przypisać / powiązać z serwerem aplikacji, jest już zajęty . Możesz przypisać inny port do swojej aplikacji.

Lub jeśli chcesz przypisać ten sam port do aplikacji. Następnie zabij aplikację działającą na wybranym porcie.

W przypadku aplikacji węzłowej możesz spróbować znaleźć identyfikator procesu dla aplikacji węzłowej poprzez:

ps -aux | grep node

Po uzyskaniu identyfikatora procesu zrób

kill process_id

-aux na Windows 10?
Tom Stickel,

Brak opcji -aux dotyczy systemów opartych na systemie Linux. W przypadku systemów opartych na systemie Windows można sprawdzić montaż systemu dla żądanego procesu węzła i zakończyć go.
Parth Vyas,

2

W Debianie dowiedziałem się, że działa na porcie 80, musisz wydać polecenie jako root, tj

sudo node app.js

Mam nadzieję, że to pomoże


2

W moim przypadku serwer HTTP Apache działał na porcie 80. Rozwiązałem go, wydając polecenie jako root

sudo killall httpd

Aktualizacja

Jeśli Jenkin jest zainstalowany i działa na komputerze Mac;

  1. Możesz to sprawdzić za pomocą sudo lsof -i tcp:8080
  2. Jeśli tak, a chcesz zatrzymać Jenkinsa tylko raz, uruchom: sudo launchctl unload /Library/LaunchDaemons/org.jenkins-ci.plist

2

Wydaje się, że jest uruchomiony inny proces obsługi węzła Node ng. Sprawdź to, wpisując to w konsoli (Linux / Mac):

ps aux|grep node

i wyjdź z:

kill -9 <NodeProcessId>

LUB użycie alternatywne

ng serve --port <AnotherFreePortNumber>

aby obsłużyć swój projekt na dowolnym wolnym porcie.


1

Zabijając NODE_PORT, może zabić twój proces chrome lub cokolwiek, co nasłuchuje na tym samym porcie, co jest denerwujące.

Ten skrypt powłoki może być pomocny - w moim przypadku port to 1337, ale możesz go zmienić w dowolnym momencie

# 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

W moim przypadku korzystam z hostingu, ale tak samo jest z hostem lokalnym, użyłem:

ps -aef | grep 'node' 

aby następnie obejrzeć proces węzła, konsola pokazuje proces z PID. aby zabić proces, musisz użyć tego polecenia:

kill -9 PID

gdzie PID jest identyfikatorem procesu z powyższej komendy.


1

Dwa serwery nie mogą nasłuchiwać na tym samym porcie, więc sprawdź, czy inny serwer nasłuchuje na tym samym porcie, a także sprawdź synchronizację przeglądarki, jeśli działa na tym samym porcie


1

Dla innych osób w localhostsystemie Windows 10 z węzłem as i działającym na porcie takim jak 3500, a nie 80 ...

Co nie działa:

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

Co pokazuje informacje, ale nadal nie działa:

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

Co działa:

Git Bash lub Powershell w systemie Windows

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

Zauważ PID (skrajnie prawy),
że nie mogłem dostać się killalldo pracy ... więc

  1. Otwórz menedżera zadań
  2. Na karcie procesów kliknij prawym przyciskiem myszy nazwę lub dowolną kolumnę i wybierz opcję uwzględnienia PID
  3. Sortuj według PID, następnie kliknij prawym PID prawym przyciskiem myszy i zakończ zadanie.

Teraz po tym niezbyt przyjemnym ćwiczeniu w systemie Windows zdałem sobie sprawę, że mogę użyć menedżera zadań, znaleźć silnik Node i po prostu go zakończyć.

Do twojej wiadomości, użyłem Visual Studio Code do uruchomienia Node na porcie 3500 i używam powłoki Git Bash wewnątrz kodu VS. Opuściłem z wdziękiem Ctrl + C, ale czasem to nie zabija. Nie chcę zmieniać portu ani restartować, więc to zadziałało. Mam nadzieję, że pomaga innym. W przeciwnym razie jest to dokumentacja dla mnie.


1

W systemie Windows użytkownicy wykonują następujące polecenie w oknie programu PowerShell, aby zabić wszystkie procesy węzłów.

Stop-Process -processname node

1

Opcja, która działa dla mnie:

Biegać:

ps -ax | grep node

Dostaniesz coś takiego:

 8078 pts/7    Tl     0:01 node server.js
 8489 pts/10   S+     0:00 grep --color=auto node    
 kill -9 8078
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.