Ошибка «Failed to bind to port» после перезапуска: почему порт остаётся занят и как это лечить
Введение: порт-призрак
Вы только что остановили сервер командой stop, через 10 секунд запускаете его снова — и получаете ошибку «Failed to bind to port 25565». Порт всё ещё занят, хотя сервер уже не работает. Это явление называется «порт в состоянии TIME_WAIT». После закрытия TCP-соединения операционная система удерживает порт в течение 30-120 секунд, прежде чем освободить его полностью. В этом гайде — почему это происходит и как обойти ожидание.
Почему порт остаётся занят после остановки сервера
TCP-протокол устроен так, что после закрытия соединения порт переходит в состояние TIME_WAIT на удвоенное время максимальной жизни пакета (обычно 60-120 секунд). Это защита от «запоздавших» пакетов, которые могут прийти уже после закрытия соединения. Если новый сервер займёт тот же порт сразу, он может получить чужие пакеты. Операционная система перестраховывается и не даёт занять порт повторно.
Решение 1: Подождать (самое простое)
Просто подождите 60-120 секунд после команды stop перед повторным запуском. В большинстве случаев этого достаточно — порт освободится автоматически.
Решение 2: Использовать SO_REUSEADDR (Java-флаг)
Java позволяет включить опцию повторного использования адреса. Добавьте флаг в параметры запуска:
java -Xmx4G -Xms4G -Djava.net.preferIPv4Stack=true -jar server.jar nogui
Флаг -Djava.net.preferIPv4Stack=true заставляет Java использовать IPv4 стек, где TIME_WAIT часто короче. Однако это не даёт 100% гарантии.
Решение 3: Уменьшить TIME_WAIT на уровне ОС
Windows
Добавьте параметр реестра:
- Win+R → regedit.
- Перейдите:
HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesTcpipParameters. - Создайте DWORD (32 бита):
TcpTimedWaitDelay. - Установите значение 30 (десятичное) — это 30 секунд вместо 120.
- Перезагрузите компьютер.
Linux
Выполните команду:sysctl -w net.ipv4.tcp_tw_reuse=1
Это разрешает повторное использование сокетов в TIME_WAIT для исходящих соединений. Для входящих может потребоваться tcp_tw_recycle (устарело в новых ядрах).
Решение 4: Скрипт с принудительным освобождением порта
Создайте скрипт start.bat (Windows):
@echo off
echo Checking port 25565...
FOR /F "tokens=5" %%P IN ('netstat -ano ^| findstr :25565 ^| findstr LISTENING') DO (
echo Killing process %%P on port 25565...
taskkill /F /PID %%P
timeout /t 5
)
echo Starting server...
java -Xmx4G -Xms4G -jar server.jar nogui
Этот скрипт перед каждым запуском проверяет, занят ли порт, и принудительно убивает процесс, который его слушает.
Решение 5: Использовать другой порт для перезапуска
Если вы часто перезапускаете сервер (например, при отладке), временно укажите другой порт в server.properties: server-port=25566. После стабилизации верните на 25565.
Типичные ошибки администраторов
- Панический перезапуск сервера. Админ видит ошибку, судорожно жмёт start.bat несколько раз — создаётся несколько процессов, которые все пытаются занять порт. Не делайте так.
- Убивают процесс через Task Manager вместо команды stop. После kill -9 на Linux порт гарантированно уходит в TIME_WAIT. Используйте
stop. - Не проверяют, точно ли сервер остановился. Команда
stopможет занять 10-30 секунд (сохранение мира). Не запускайте новый экземпляр, пока старый не завершился полностью.
💡 Совет профи
Настройте systemd-сервис (Linux) для Minecraft-сервера с параметромRestart=alwaysиRestartSec=10. Systemd сам подождёт 10 секунд между остановкой и запуском, что обычно достаточно для освобождения порта. А если настроитьExecStop=/bin/bash -c 'sleep 5; kill %n', вы получите контролируемый перезапуск без гонки за портом.
💬 Комментарии (0)
🔒 Войдите, чтобы оставить комментарий
😊 Пока нет комментариев. Будьте первым!