Skip to content

Ports und localhost

💡 Lernleitfaden: Wenn du npm run dev ausführst und im Terminal http://localhost:5173 erscheint, hast du dich dann schon einmal gefragt: Was ist localhost? Wofür steht 5173? Warum meldet es manchmal den Fehler EADDRINUSE? Dieses Kapitel erklärt dir diese Konzepte, die dir in der täglichen Entwicklung ständig begegnen, aber über die du selten tiefer nachdenkst, ein für alle Mal.

Bevor du beginnst, empfehle ich dir, diese zwei „Grundbausteine" nachzuholen:


0. Einleitung: Was genau ist das alltägliche localhost:5173?

1
2
3
4
5
1. You run npm run dev
Terminal
$ npm run dev

> vite

  准备就绪...
Listening
Browser
等待你打开Browser...
💡 You type the start command in terminal
What is an HTTP Server?
🏪
Imagine a service windowHTTP 服务器就像一个"永远开着的服务窗口"——它一直等在那里,有人来问就回答,没人来就静静等着。
📋
Only understands one "code"这个窗口只听得懂 HTTP 协议的请求格式(比如 GET /index.html),然后把对应的文件内容返回给你。
⚙️
Dev Server = Enhanced WindowVite、Webpack 的开发服务器不只是"原样返回文件",它还会即时编译你的代码(Vue → JS、TS → JS、Sass → CSS),然后再返回给Browser。
One-line Summary:Dev server = An HTTP server running on localhost + Real-time code compiler. It listens on a port, and when browser requests, it returns the compiled code.

Kein Entwickler kommt an dieser Ausgabezeile vorbei:

➜  Local:   http://localhost:5173/

Aber hast du dich schon einmal gefragt, dass in dieser kurzen Zeile mehrere Schlüsselkonzepte stecken:

  • http:// -> Kommunikationsprotokoll (in welcher Sprache kommuniziert wird)
  • localhost -> Zieladresse (mit wem kommuniziert wird)
  • :5173 -> Portnummer (an welche Tür geklopft wird)

Wenn du diese drei Dinge verstehst, verstehst du 90 % aller Netzwerkprobleme in der Entwicklungsumgebung. Lasst sie uns einzeln auseinandernehmen.


1. Was ist ein Port? (IP ist das Gebäude, Port ist die Zimmernummer)

1.1 Eine intuitive Analogie

Stell dir einen Server als ein großes Gebäude vor:

  • Die IP-Adresse (z. B. 192.168.1.100) ist die Hausnummer des Gebäudes – sie sagt dir, „in welches Gebäude".
  • Die Portnummer (z. B. :80) ist die Zimmernummer im Gebäude – sie sagt dir, „in welches Zimmer".

In einem Gebäude kann es gleichzeitig ein Restaurant (Zimmer 80), ein Cafe (Zimmer 443) und ein Buero (Zimmer 22) geben. Genauso kann auf einem Computer gleichzeitig ein Webserver, eine Datenbank und ein SSH-Dienst laufen – jeder auf einem anderen Port.

👇 Probiere es aus: Klicke auf die „Zimmernummern" unten, um Verbindungen zu verschiedenen Ports zu simulieren. Beobachte, was passiert, wenn ein Port „offen" (ein Programm lauscht) oder „geschlossen" ist.

Select a "building":
Web Server BuildingIP: 192.168.1.100
80
HTTPWeb access entry
🟢 Listening
443
HTTPSEncrypted web entry
🟢 Listening
22
SSHRemote management channel
🟢 Listening
3306
MySQLDatabase (closed)
🔴 Closed
Core Analogy:IP 地址 = 大楼地址,端口号 = 房间门牌号。一台电脑上可以同时运行多个服务,每个服务"占用"一个端口号,就像同一栋大楼里的不同房间。

1.2 Wertebereich der Portnummern

Portnummern sind ganze Zahlen zwischen 0 und 65535 (insgesamt 65.536). Diese vielen Ports sind in drei Bereiche unterteilt:

BereichSpanneVerwendungBeispiele
System-Ports0 – 1023Reserviert für Standardprotokolle, normale Benutzer können sie nicht belegen80 (HTTP), 443 (HTTPS), 22 (SSH)
Registrierte Ports1024 – 49151Zur Registrierung durch gängige Anwendungen3306 (MySQL), 5432 (PostgreSQL), 6379 (Redis)
Dynamische Ports49152 – 65535Temporär vom Betriebssystem zugewiesenDer Browser weist beim Senden einer Anfrage zufällig einen Quellport zu

Warum nutzen deine Entwicklungsserver gerne 3000, 5173, 8080? Weil diese alle im Bereich der „registrierten Ports" liegen, keine Administratorrechte zum Lauschen erfordern und gleichzeitig weniger wahrscheinlich mit Systemdiensten kollidieren.

1.3 Schnellübersicht gängiger Ports in der Entwicklung

👇 Probiere es aus: Gib eine Portnummer oder einen Dienstnamen für die Suche ein. Klicke auf eine Zeile, um Anwendungsbeispiele anzuzeigen.

PortServiceDescriptionExposure Risk
80HTTP网页访问(未加密)安全
443HTTPS网页访问(加密)安全
22SSH安全远程登录注意
21FTP文件传输敏感
3306MySQLMySQL 数据库敏感
5432PostgreSQLPostgreSQL 数据库敏感
27017MongoDBMongoDB 数据库敏感
6379RedisRedis 缓存敏感
3000Node/ReactNode.js / React 开发服务器安全
5173ViteVite 开发服务器安全
8080通用 HTTPHTTP 备用端口 / 代理安全
8000Django/PythonDjango / Python HTTP 服务安全
5000FlaskFlask 开发服务器安全
4200AngularAngular 开发服务器安全
53DNS域名解析注意
25SMTP邮件发送注意
0 – 1023
System PortsReserved for standard services (HTTP, SSH, etc.), regular users cannot occupy.
1024 – 49151
Registered PortsFor common applications (MySQL 3306, Redis 6379, etc.), most encountered in development.
49152 – 65535
Dynamic PortsTemporarily assigned by OS, like when your browser makes requests, system randomly assigns one.
Security Alert:数据库端口(3306、5432、27017、6379)绝对不要直接暴露到公网!生产环境应只允许内网访问或通过 SSH 隧道连接。

2. Was ist localhost? (Sich selbst finden)

2.1 Das Kernkonzept des „Loopbacks"

localhost ist ein spezieller Domainname, der immer auf deinen eigenen Computer verweist.

Wenn du http://localhost:3000 in den Browser eingibst, passiert Folgendes:

  1. Der Browser fragt das Betriebssystem: „Wie lautet die IP von localhost?"
  2. Das Betriebssystem antwortet direkt: „127.0.0.1" (kein DNS im Internet nötig)
  3. Das Datenpaket wird an 127.0.0.1 gesendet, verlässt aber nie tatsächlich den Rechner
  4. Das Betriebssystem schickt das Datenpaket über das Loopback-Interface zurück
  5. Das auf Port 3000 lauschende Programm empfängt die Anfrage und sendet die Antwort

Der gesamte Prozess geht nicht ueber ein Netzwerkkabel, keinen Router und benötigt keine Internetverbindung.

👇 Probiere es aus: Klicke auf „Anfrage senden", um die vollständige Reise des Datenpakets zu beobachten. Klicke dann auf die „Alias-Karten" unten, um die verschiedenen Schreibweisen und Unterschiede von localhost kennenzulernen.

🔗
🌐
BrowserYou enter URL in address bar
📖
DNS Resolutionlocalhost → 127.0.0.1 (no internet)
🔄
Network LayerPacket sent to 127.0.0.1 (loopback interface)
⚙️
Local ServiceProgram on port 3000 receives request
📨
Return Response{ "message": "Hello!" }
Your App(Browser)
Request stays on local machine
Local Service(:3000)
Localhost "Aliases" (click to see description)
localhost→ 127.0.0.1
127.0.0.1→ 127.0.0.1
::1→ ::1
0.0.0.0→ 0.0.0.0
This is mapped in your computer's <code>/etc/hosts</code> file. When browser sees <code>localhost</code>, it directly resolves to <code>127.0.0.1</code> without asking DNS server.: 这是写在你电脑 /etc/hosts 文件里的映射。浏览器看到 localhost 时,直接解析为 127.0.0.1,不会去问 DNS 服务器。
Core Concept:localhost 就是"自己找自己"。数据包通过环回接口(loopback interface)在本机内部折返,不经过网线、不经过路由器,速度极快且完全安全。

2.2 localhost vs. 127.0.0.1 vs. 0.0.0.0

Diese drei Konzepte werden oft verwechselt, haben aber völlig unterschiedliche Bedeutungen:

SchreibweiseBedeutungWer kann zugreifen
localhost / 127.0.0.1Loopback-Adresse, nur der eigene RechnerNur dein eigener Computer
0.0.0.0Lauscht auf allen NetzwerkschnittstellenEigener Rechner + andere Geräte im LAN
192.168.x.xLAN-IP-AdresseGeräte im lokalen Netzwerk

Praktisches Szenario:

bash
# Nur du selbst kannst zugreifen (sicher, geeignet für Entwicklung)
npm run dev -- --host localhost

# Auch das Handy kann zugreifen (geeignet für Mobile-Debugging)
npm run dev -- --host 0.0.0.0

Viele Frameworks (wie Vite, Next.js) lauschen standardmäßig auf localhost, sodass dein Handy selbst im gleichen WLAN nicht zugreifen kann. Du willst mit dem Handy debuggen? Füge einfach den Parameter --host hinzu.


3. Portkonflikte: Das häufigste Problem in der Entwicklungsumgebung

3.1 Warum kommt es zu Konflikten?

Ein einzelner Port kann zur gleichen Zeit nur von einem Programm belauscht werden. Genau wie ein Zimmer nur von einer Familie bewohnt werden kann.

Wenn du versuchst, einen zweiten Dienst auf demselben Port zu starten, siehst du diesen klassischen Fehler:

Error: listen EADDRINUSE :::3000

In menschliche Sprache uebersetzt: „Zimmer 3000 ist bereits belegt, du kommst nicht rein!"

Häufige Konfliktszenarien:

  • Der vorherige Entwicklungsserver wurde nicht sauber beendet und läuft noch im Hintergrund
  • Zwei verschiedene Projekte verwenden denselben Standardport
  • Ein Systemdienst belegt bereits den von dir gewünschten Port

👇 Probiere es aus: Versuche, im untenstehenden Simulator mehrmals einen Dienst zu starten. Vergleiche bei einem Portkonflikt die unterschiedlichen Verhaltensweisen von „Direktstart" und „Intelligentem Start".

Try starting:React(default port 5173)
Currently Running Services1 services
Vite:5173🟢 Running
Port Conflict:一个端口同一时刻只能被一个程序监听。如果你看到 EADDRINUSE 错误,说明这个端口已经被占了。要么杀掉旧进程,要么换个端口。

3.2 Fehlersuche und Lösung

Wenn du auf einen Portkonflikt stößt, ist der Ablauf zur Fehlersuche immer gleich:

macOS / Linux:

bash
# Schritt 1: Ermitteln, wer Port 3000 belegt
lsof -i :3000

# Schritt 2: PID aus Schritt 1 nehmen und den Prozess hart beenden
kill -9 <PID>

Windows:

bash
# Schritt 1: Ermitteln, wer Port 3000 belegt
netstat -ano | findstr :3000

# Schritt 2: Prozess beenden
taskkill /PID <PID> /F

Viele moderne Frameworks (Vite, Create React App usw.) fragen bei Portkonflikten automatisch: „Anderen Port verwenden?" Aber wenn du das zugrunde liegende Prinzip verstehst, kannst du Probleme schneller diagnostizieren, bei denen dir das Framework nicht helfen kann.


4. Die „Same-Origin Policy" und Cross-Origin in der Entwicklung

4.1 Was ist ein „Origin"?

Browser haben einen Sicherheitsmechanismus namens Same-Origin Policy: Nur wenn Protokoll, Domain und Port alle drei vollständig identisch sind, gilt es als „same origin".

Adresse AAdresse BSame Origin?Grund
http://localhost:5173http://localhost:5173/about✅ Same OriginProtokoll, Domain, Port alle gleich
http://localhost:5173http://localhost:3000❌ Cross-OriginPort unterschiedlich (5173 vs. 3000)
http://localhost:5173https://localhost:5173❌ Cross-OriginProtokoll unterschiedlich (http vs. https)

4.2 Warum stößt die Trennung von Frontend und Backend zwangsläufig auf Cross-Origin?

Wenn deine Projektarchitektur so aussieht:

Frontend (Vite)   ->  http://localhost:5173
Backend (Express) ->  http://localhost:3000

Die Frontend-Seite wird von :5173 geladen und verwendet dann fetch('/api/users'), um die API unter :3000 anzufragen – die Ports sind unterschiedlich, die Cross-Origin-Beschränkung greift!

Zwei gängige Lösungen:

Lösung 1: CORS im Backend konfigurieren

javascript
// Express Backend
app.use(cors({ origin: 'http://localhost:5173' }))

Lösung 2: Proxy im Frontend konfigurieren (empfohlen)

javascript
// vite.config.js
export default {
  server: {
    proxy: {
      '/api': 'http://localhost:3000'
    }
  }
}

Das Prinzip des Proxys: Der Vite-Entwicklungsserver leitet deine Anfragen weiter. Der Browser denkt, er kommuniziert mit :5173 (same origin), tatsächlich leitet Vite die Anfrage im Hintergrund heimlich an :3000 weiter.


5. Praktische Fehlersuche: Die drei häufigsten Probleme

👇 Probiere es aus: Wähle ein Problem, das du schon einmal hattest, und folge den Schritten zur Fehlersuche. Jeder Schritt kann durch Klicken auf „Ausführen" angezeigt werden.

Select a common issue:
🔴
Port OccupiedError: listen EADDRINUSE :::3000
Troubleshooting Steps (1/3)
$lsof -i :3000
Check who is using this port
Troubleshooting Mantra:先确认服务有没有启动(lsof / netstat),再确认端口对不对,最后确认是不是跨域问题。90% 的 localhost 问题都逃不出这三步。

6. Begriffsglossar

Englischer BegriffDeutsche EntsprechungErklärung
PortPortEine Zahl zwischen 0 und 65535 zur Unterscheidung verschiedener Netzwerkdienste auf demselben Rechner. Jeder Dienst „lauscht" auf einem Port und wartet auf Client-Verbindungen.
localhostLokaler HostEin spezieller Domainname, der immer auf den eigenen Rechner (127.0.0.1) verweist. Ermöglicht den Zugriff auf lokal laufende Dienste ohne Internetverbindung.
Loopback InterfaceLoopback-SchnittstelleDie virtuelle Netzwerkschnittstelle des Betriebssystems. Datenpakete an 127.0.0.1 verlassen den Rechner nicht, sondern werden über diese Schnittstelle „zurückgeschickt".
EADDRINUSEAdresse bereits verwendetEin von Node.js / dem Betriebssystem gemeldeter Fehler: Der gewünschte Port wird bereits von einem anderen Programm belegt.
CORSCross-Origin Resource SharingEin Browser-Sicherheitsmechanismus. Wenn eine Frontend-Seite versucht, eine API mit anderem Origin (Protokoll/Domain/Port) anzufragen, benötigt sie eine ausdrückliche Erlaubnis vom Backend.
Same-Origin PolicySame-Origin-PolicyDie Sicherheitsgrundlage des Browsers: Erlaubt nur freie Kommunikation zwischen Anfragen mit gleichem Protokoll, gleicher Domain und gleichem Port – blockiert Cross-Origin-Datenzugriffe.
ProxyProxyIn der Entwicklungsumgebung leitet der Proxy-Server Anfragen stellvertretend für den Browser an das Backend weiter und umgeht so die Same-Origin-Beschränkung.
0.0.0.0Alle SchnittstellenWenn ein Dienst auf 0.0.0.0 lauscht, akzeptiert er Verbindungen von allen Netzwerkschnittstellen (eigener Rechner, LAN usw.).
Well-known PortsBekannte PortsSammelbezeichnung für die Ports 0–1023, reserviert für Standardprotokolle wie HTTP (80), HTTPS (443), SSH (22).
PIDProzess-IDEine eindeutige Nummer, die das Betriebssystem jedem laufenden Programm zuweist, zur Verwaltung und Beendigung von Prozessen.
lsofListe offener DateienmacOS/Linux-Befehl, um zu ermitteln, welcher Prozess einen bestimmten Port belegt (lsof -i :Portnummer).
HMRHot Module ReplacementFunktion des Entwicklungsservers: Wenn du Code änderst, aktualisiert sich der Browser automatisch, ohne manuelles Neuladen. Benachrichtigt den Browser im Hintergrund per WebSocket.

Zusammenfassung

Ports und localhost sind die grundlegendsten und häufigsten Konzepte in der Entwicklungsumgebung:

  • Port = Die „Zimmernummer" zur Unterscheidung verschiedener Dienste auf einem Rechner (0–65535)
  • localhost = Die spezielle Adresse „sich selbst finden" (127.0.0.1), Daten verlassen den Rechner nicht
  • Portkonflikt bedeutet im Kern: „Ein Türschild kann nur ein Namensschild tragen"
  • Cross-Origin bedeutet im Kern: „Unterschiedlicher Port = unterschiedlicher Origin", erfordert CORS oder Proxy zur Lösung

Merke dir diese vier Sätze, und du kannst die meisten Netzwerkprobleme in deiner Entwicklungsumgebung schnell diagnostizieren.