مجله ایرانیکاسرورآموزش سرور، هاست، وردپرس و شبکه
آموزشی

رفع Address Already in Use و پیدا کردن سرویس اشغال‌کننده Port

اگر هنگام اجرای یک برنامه، وب‌سرور، API، دیتابیس یا کانتینر با خطایی مثل Address already in use، EADDRINUSE، bind: address already in use یا در Docker با پیام port is already allocated روبه‌رو شده‌اید،…

رفع Address Already in Use و پیدا کردن سرویس اشغال‌کننده Port
خلاصه سریع این آموزش

اگر هنگام اجرای یک برنامه، وب‌سرور، API، دیتابیس یا کانتینر با خطایی مثل Address already in use، EADDRINUSE، bind: address already in use یا در Docker با پیام port is…

۱۶ دقیقه مطالعه ۰ دیدگاه ۱۳ مهر ۱۴۰۵ آخرین به‌روزرسانی

اگر هنگام اجرای یک برنامه، وب‌سرور، API، دیتابیس یا کانتینر با خطایی مثل Address already in use، EADDRINUSE، bind: address already in use یا در Docker با پیام port is already allocated روبه‌رو شده‌اید، معنی آن معمولاً این است که یک Process دیگر قبلاً همان IP و Port را گرفته است و برنامه جدید نمی‌تواند روی همان Socket گوش کند.

راه‌حل کوتاه: ابتدا با ss -ltnp یا ss -lunp مشخص کنید چه Processای روی پورت موردنظر Listen می‌کند. اگر به PID نیاز دارید از lsof -i :PORT یا fuser PORT/tcp کمک بگیرید. بعد بررسی کنید Process متعلق به کدام سرویس systemd، برنامه یا کانتینر Docker است. فقط اگر مطمئن شدید آن سرویس نباید فعال باشد، آن را به‌صورت اصولی Stop کنید؛ kill -9 باید آخرین انتخاب باشد، نه اولین راه‌حل.

فهرست مطالب

خطای Address Already in Use یعنی چه؟

برنامه‌هایی مثل Nginx، Apache، Node.js، Python، PHP، Redis، PostgreSQL و سرویس‌های Docker برای دریافت اتصال شبکه باید یک Socket را به یک IP و Port مشخص Bind کنند.

برای مثال ممکن است برنامه Node.js بخواهد روی پورت 3000 اجرا شود:

0.0.0.0:3000

اگر Process دیگری قبلاً همین آدرس را گرفته باشد، برنامه دوم نمی‌تواند همان ترکیب IP و Port را Bind کند و سیستم‌عامل خطای EADDRINUSE برمی‌گرداند.

نمونه خطا در Node.js:

Error: listen EADDRINUSE: address already in use :::3000

نمونه در Python:

OSError: [Errno 98] Address already in use

نمونه در یک سرویس لینوکسی:

bind() to 0.0.0.0:8080 failed (98: Address already in use)

قبل از Kill کردن Process، سرویس اشغال‌کننده پورت را پیدا کنید

اشتباه رایج این است که به‌محض دیدن خطا، Process را با kill -9 متوقف کنیم. این کار ممکن است وب‌سرور، دیتابیس، SSH Tunnel، Proxy یا سرویس مهم دیگری را از کار بیندازد.

روند درست این است:

  1. پورت مشکل‌دار را مشخص کنید.
  2. Process یا سرویس Listen‌کننده را پیدا کنید.
  3. بررسی کنید Process چرا فعال است.
  4. تصمیم بگیرید سرویس فعلی Stop شود یا پورت برنامه جدید تغییر کند.
  5. بعد از تغییر، دوباره وضعیت پورت را تست کنید.

روش اول و پیشنهادی: پیدا کردن سرویس اشغال‌کننده Port با ss

در بیشتر توزیع‌های جدید Linux، ابزار ss انتخاب مناسبی برای بررسی Socketها است.

برای مشاهده TCP Portهای در حال Listen:

sudo ss -ltnp

معنی گزینه‌ها:

  • -l: فقط Socketهای Listening را نمایش می‌دهد.
  • -t: فقط TCP را نمایش می‌دهد.
  • -n: Port و IP را عددی نشان می‌دهد.
  • -p: Process مرتبط را در صورت داشتن Permission نمایش می‌دهد.

نمونه خروجی:

State  Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0      511          0.0.0.0:80        0.0.0.0:*    users:(("nginx",pid=2140,fd=6))
LISTEN 0      4096       127.0.0.1:3000      0.0.0.0:*    users:(("node",pid=4251,fd=19))

در این مثال:

  • پورت 80 توسط Nginx با PID برابر 2140 استفاده می‌شود.
  • پورت 3000 توسط Node.js با PID برابر 4251 استفاده می‌شود.

فقط یک Port مشخص را با ss بررسی کنیم

مثلاً برای پورت 3000:

sudo ss -ltnp 'sport = :3000'

یا با grep:

sudo ss -ltnp | grep ':3000 '

روش اول دقیق‌تر است، چون از قابلیت فیلتر خود ss استفاده می‌کند.

اگر Port مربوط به UDP است

دستور TCP چیزی برای UDP نشان نمی‌دهد. برای UDP اجرا کنید:

sudo ss -lunp

برای یک UDP Port مشخص، مثلاً 53:

sudo ss -lunp 'sport = :53'

این مورد برای سرویس‌هایی مثل DNS اهمیت دارد؛ چون ممکن است پورت UDP اشغال باشد ولی شما فقط TCP را بررسی کرده باشید.

روش دوم: پیدا کردن PID با lsof

lsof ابزار مشاهده فایل‌های باز توسط Processها است و Socketهای شبکه نیز در Linux به‌عنوان File Descriptor مدیریت می‌شوند.

برای پورت 8080:

sudo lsof -i :8080

نمونه:

COMMAND PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
java    7421 app    64u  IPv6  91944      0t0  TCP *:8080 (LISTEN)

در این خروجی Process با نام java و PID برابر 7421 پورت را در اختیار دارد.

برای نمایش فقط TCP Listener روی همان Port:

sudo lsof -nP -iTCP:8080 -sTCP:LISTEN

اگر lsof نصب نیست

در Ubuntu و Debian:

sudo apt update
sudo apt install lsof

در Rocky Linux، AlmaLinux یا RHEL:

sudo dnf install lsof

روش سوم: پیدا کردن PID با fuser

برای TCP Port 3000:

sudo fuser 3000/tcp

نمونه خروجی:

3000/tcp:            4251

برای نمایش اطلاعات بیشتر:

sudo fuser -v 3000/tcp

برای UDP:

sudo fuser -v 53/udp

هشدار: fuser امکان Kill کردن Process را هم دارد، اما قبل از استفاده از گزینه‌های Kill ابتدا سرویس و نقش PID را مشخص کنید. آزاد کردن پورت با متوقف کردن اشتباهی سرویس حیاتی می‌تواند باعث Downtime شود.

PID پیدا شد؛ حالا بفهمیم Process چیست

فرض کنیم PID برابر 4251 است.

اطلاعات Process:

ps -fp 4251

Command Line کامل:

tr '\0' ' ' < /proc/4251/cmdline
echo

مسیر فایل اجرایی:

readlink -f /proc/4251/exe

دایرکتوری کاری Process:

readlink -f /proc/4251/cwd

این اطلاعات کمک می‌کند بفهمید Process مربوط به کدام برنامه یا پروژه است.

چطور بفهمیم PID مربوط به کدام سرویس systemd است؟

یکی از روش‌های ساده:

systemctl status 4251

اگر Process عضو یک Unit شناخته‌شده systemd باشد، معمولاً اطلاعات Service نمایش داده می‌شود.

همچنین می‌توانید ساختار Cgroup را ببینید:

cat /proc/4251/cgroup

اگر مثلاً مشخص شد Process متعلق به nginx.service است، به‌جای Kill کردن مستقیم PID بهتر است Service را مدیریت کنید:

sudo systemctl status nginx
sudo systemctl stop nginx

روش اصولی آزاد کردن Port

اگر پس از بررسی مطمئن شدید Process قبلی نباید اجرا شود، ابتدا روش Graceful را امتحان کنید.

اگر systemd Service است:

sudo systemctl stop SERVICE_NAME

مثلاً:

sudo systemctl stop nginx

بعد Port را بررسی کنید:

sudo ss -ltnp 'sport = :80'

اگر Process مستقل است

برای Process مستقل ابتدا SIGTERM بفرستید:

kill 4251

این فرمان به‌طور پیش‌فرض SIGTERM می‌فرستد و به برنامه فرصت می‌دهد Shutdown تمیز انجام دهد.

چند ثانیه بعد:

ps -p 4251
sudo ss -ltnp 'sport = :3000'

فقط اگر Process به SIGTERM پاسخ نداد و مطمئن هستید توقف اجباری بی‌خطر است، SIGKILL را در نظر بگیرید:

kill -9 4251

چرا kill -9 انتخاب اول نیست؟ SIGKILL به Process فرصت Cleanup، Flush کردن داده، بستن Connectionها یا حذف Lock File را نمی‌دهد. برای دیتابیس و برنامه‌های دارای داده حساس این تفاوت مهم است.

اگر سرویس را Stop می‌کنیم ولی دوباره برمی‌گردد

اگر Process بلافاصله با PID جدید ظاهر می‌شود، احتمالاً تحت کنترل systemd، Supervisor، Docker، Kubernetes یا یک Process Manager مانند PM2 است.

مثلاً بعد از Kill:

sudo ss -ltnp 'sport = :3000'

اگر PID جدیدی ظاهر شد، Root Cause را پیدا کنید؛ Kill کردن مکرر راه‌حل نیست.

اگر برنامه با PM2 اجرا شده است

برنامه‌های Node.js ممکن است توسط PM2 مدیریت شوند:

pm2 list

برای توقف یک برنامه:

pm2 stop APP_NAME

اگر برنامه نباید دیگر اجرا شود:

pm2 delete APP_NAME

رفع Address Already in Use در Docker

در Docker دو Port مهم داریم:

  • Container Port: پورتی که برنامه داخل Container استفاده می‌کند.
  • Published Host Port: پورتی که روی Host منتشر شده است.

مثلاً:

docker run -p 8080:80 nginx

یعنی Port 8080 روی Host به Port 80 داخل Container متصل می‌شود.

اگر Host Port 8080 قبلاً استفاده شده باشد، Container جدید نمی‌تواند همان Port را Publish کند.

ببینید کدام Container پورت را گرفته است

docker ps --format 'table {{.ID}}\t{{.Names}}\t{{.Ports}}'

نمونه:

CONTAINER ID   NAMES       PORTS
a91c44f21c12   old-api     0.0.0.0:8080->80/tcp
bc319cd92011   postgres    0.0.0.0:5432->5432/tcp

در این مثال Container با نام old-api پورت 8080 Host را گرفته است.

جست‌وجوی سریع Docker بر اساس Port

docker ps --filter publish=8080

اگر Container موردنظر دیگر لازم نیست:

docker stop old-api

و اگر باید حذف شود:

docker rm old-api

اگر مشکل در Docker Compose است

فرض کنید Compose این تنظیم را دارد:

services:
  app:
    image: myapp
    ports:
      - "8080:80"

اگر پورت 8080 روی Host اشغال باشد، یکی از راه‌ها انتخاب Port دیگری است:

services:
  app:
    image: myapp
    ports:
      - "8081:80"

سپس:

docker compose up -d

در این حالت برنامه داخل کانتینر همچنان Port 80 دارد، اما از بیرون با Port 8081 Host در دسترس است.

اگر ss فقط docker-proxy نشان می‌دهد

در بعضی تنظیمات Docker ممکن است Process مربوط به Port به‌شکل docker-proxy دیده شود:

sudo ss -ltnp 'sport = :8080'

در این حالت ابتدا Containerهای دارای Published Port را بررسی کنید:

docker ps --filter publish=8080

به‌جای Kill کردن مستقیم docker-proxy، Container مسئول آن Port را مدیریت کنید.

مقاله مرتبط

اگر Port آزاد است اما سایت یا سرویس VPS همچنان از بیرون باز نمی‌شود، مشکل می‌تواند از Firewall، Listen Address، Reverse Proxy یا شبکه باشد. در این حالت مقاله عیب‌یابی باز نشدن سایت روی VPS می‌تواند مرحله بعدی بررسی باشد.

تداخل IPv4 و IPv6 را هم بررسی کنید

گاهی خطا کمی گیج‌کننده است؛ چون برنامه روی IPv4 چیزی نشان نمی‌دهد اما Bind روی IPv6 انجام شده است.

هم TCP IPv4 و هم IPv6 را ببینید:

sudo ss -ltnp

ممکن است خروجی شامل یکی از این‌ها باشد:

0.0.0.0:8080
127.0.0.1:8080
[::]:8080
[::1]:8080

0.0.0.0 یعنی برنامه روی همه IPv4 Addressهای سیستم Listen می‌کند. [::] نیز معمولاً به همه IPv6 Addressها اشاره دارد و بسته به تنظیمات Socket و سیستم ممکن است روی Bind برنامه دوم اثر بگذارد.

یک Port می‌تواند روی IPهای مختلف استفاده شود؟

بله، در بعضی شرایط دو سرویس می‌توانند یک شماره Port یکسان داشته باشند اگر روی IPهای محلی متفاوت Bind شوند.

مثلاً:

127.0.0.1:8080
192.0.2.10:8080

اما اگر یکی از برنامه‌ها روی:

0.0.0.0:8080

Listen کند، معمولاً تمام IPv4 Addressهای محلی را برای آن Port پوشش می‌دهد و برنامه دیگری نمی‌تواند به‌سادگی Port 8080 را روی یکی از همان IPها بگیرد.

127.0.0.1 با 0.0.0.0 چه تفاوتی دارد؟

اگر سرویس فقط باید توسط Reverse Proxy محلی مصرف شود، معمولاً Bind روی Loopback امن‌تر است:

127.0.0.1:3000

اما:

0.0.0.0:3000

به معنی Listen روی همه IPv4 Interfaceهای محلی است.

گاهی دو نسخه از یک برنامه با تنظیم متفاوت Bind شده‌اند و همین موضوع باعث Conflict می‌شود.

تداخل Nginx و Apache روی Port 80 یا 443

یکی از سناریوهای بسیار رایج این است که هم Nginx و هم Apache تلاش می‌کنند روی Port 80 اجرا شوند.

بررسی:

sudo ss -ltnp 'sport = :80'
sudo ss -ltnp 'sport = :443'

سپس:

sudo systemctl status nginx
sudo systemctl status apache2

اگر Nginx قرار است Reverse Proxy باشد، معمولاً Backend باید روی Port دیگری مثل 8080 یا Loopback اجرا شود؛ نه اینکه هر دو روی 0.0.0.0:80 Bind شوند.

Node.js دو بار اجرا شده است

در پروژه Node.js ممکن است برنامه را دستی اجرا کرده باشید:

node server.js

در حالی که همان برنامه قبلاً با PM2 یا systemd فعال بوده است.

پورت را بررسی کنید:

sudo ss -ltnp 'sport = :3000'

و Processهای Node:

ps aux | grep '[n]ode'

اگر PM2 دارید:

pm2 list

Flask یا Python: Port قبلاً گرفته شده است

مثلاً Flask روی Port 5000:

sudo ss -ltnp 'sport = :5000'

یا:

sudo lsof -nP -iTCP:5000 -sTCP:LISTEN

اگر نسخه قبلی برنامه هنوز فعال است، همان Process را به‌صورت اصولی Stop کنید یا Port نسخه جدید را تغییر دهید.

Redis و PostgreSQL را بدون بررسی متوقف نکنید

پورت‌های رایج:

Redis:      6379
PostgreSQL: 5432
MySQL:      3306

اگر برنامه شما می‌خواهد روی یکی از این Portها اجرا شود و PID متعلق به دیتابیس است، احتمالاً مشکل از انتخاب Port برنامه شماست، نه دیتابیس.

هشدار: صرفاً برای آزاد کردن Port، دیتابیس Production را Stop یا Kill نکنید. ابتدا مشخص کنید کدام سرویس باید واقعاً از آن Port استفاده کند.

گاهی systemd Socket خودش Port را گرفته است

در بعضی سرویس‌ها systemd قبل از اجرای Service، Socket را باز می‌کند. در این حالت فقط بررسی Service کافی نیست.

Socket Unitهای فعال:

systemctl list-sockets

اگر Socket Unit خاصی Port را مدیریت می‌کند، وضعیت آن را بررسی کنید:

systemctl status NAME.socket

در چنین سناریویی Kill کردن Process فرزند ممکن است باعث آزاد ماندن دائمی Port نشود، چون خود Socket Unit همچنان فعال است.

آیا TIME_WAIT باعث Address Already in Use می‌شود؟

گاهی بعد از Restart سریع برنامه تعداد زیادی Connection در حالت TIME-WAIT دیده می‌شود:

ss -tan state time-wait

اما وجود TIME_WAIT به‌تنهایی به این معنی نیست که یک Listener فعال همان Port را اشغال کرده است. برای خطای Bind ابتدا Listenerها را بررسی کنید:

sudo ss -ltnp

رفتار دقیق Bind مجدد به تنظیمات Socket مانند SO_REUSEADDR و نوع Connection بستگی دارد؛ بنابراین پیشنهاد نمی‌شود صرفاً به خاطر مشاهده TIME_WAIT تنظیمات Kernel را تغییر دهید.

اگر برنامه می‌گوید Port اشغال است ولی ss چیزی نشان نمی‌دهد

چند مورد را بررسی کنید:

  • پروتکل را اشتباه بررسی نکرده باشید؛ TCP در برابر UDP.
  • IPv6 Listener را نادیده نگرفته باشید.
  • فرمان را بدون Permission کافی اجرا نکرده باشید.
  • برنامه با Unix Socket کار نکند.
  • خطا مربوط به Port موقتی یا Race Condition نباشد.
  • Process بین دو بار بررسی سریع Start و Stop نشود.

بررسی گسترده:

sudo ss -lntup

Address Already in Use برای Unix Socket

این خطا فقط مخصوص TCP/UDP Port نیست. برنامه‌ها می‌توانند روی Unix Domain Socket نیز Bind کنند.

مثلاً:

/run/myapp/app.sock

برای مشاهده Unix Socketها:

sudo ss -lxnp

اگر Socket File باقی مانده ولی Process مربوطه دیگر وجود ندارد، باید اول مطمئن شوید Socket واقعاً Stale است. حذف کورکورانه Socket فایل یک سرویس فعال می‌تواند مشکل ایجاد کند.

گاهی بهتر است Port برنامه جدید را تغییر دهید

اگر Port فعلی به سرویس مهم دیگری تعلق دارد، بهترین راه آزاد کردن آن نیست؛ Port برنامه جدید را عوض کنید.

مثلاً برنامه Node.js:

PORT=3001 node server.js

یا در فایل Environment:

PORT=3001

بعد از تغییر پورت، Reverse Proxy، Firewall، Health Check و تنظیمات سرویس‌هایی که به برنامه وصل می‌شوند را نیز بررسی کنید.

تست نهایی بعد از رفع تداخل Port

فرض کنیم سرویس باید روی پورت 3000 باشد.

اول Listener را ببینید:

sudo ss -ltnp 'sport = :3000'

بعد از داخل خود سرور Connection را تست کنید:

curl -v http://127.0.0.1:3000/

اگر HTTP نیست، صرفاً بازبودن TCP را می‌توانید با ابزارهایی مانند netcat بررسی کنید:

nc -vz 127.0.0.1 3000

اگر nc نصب نیست، نصب بسته بسته به توزیع Linux متفاوت است.

بعد از Start مجدد، لاگ سرویس را بررسی کنید

برای systemd:

sudo systemctl restart SERVICE_NAME
sudo systemctl status SERVICE_NAME
sudo journalctl -u SERVICE_NAME -n 100 --no-pager

برای Docker Compose:

docker compose up -d
docker compose ps
docker compose logs --tail=100

روال امن رفع Address Already in Use

  1. Port و Protocol موردنظر را مشخص کنید.
  2. با ss Listener فعال را پیدا کنید.
  3. با lsof یا fuser PID را تأیید کنید.
  4. با ps و اطلاعات /proc برنامه را شناسایی کنید.
  5. بررسی کنید Process متعلق به systemd، Docker، PM2 یا سرویس دیگری است.
  6. مشخص کنید سرویس قبلی باید Stop شود یا Port سرویس جدید تغییر کند.
  7. برای Stop ابتدا روش Graceful را استفاده کنید.
  8. بعد از تغییر، با ss وضعیت Port را دوباره بررسی کنید.
  9. سرویس را Start کنید و لاگ آن را بخوانید.
  10. با curl یا ابزار مناسب عملکرد واقعی سرویس را تست کنید.

اجرای سرویس‌های لینوکسی روی VPS

اگر برای Docker، Node.js، Python، وب‌سرور، دیتابیس یا سرویس‌های Self-hosted به زیرساخت لینوکسی نیاز دارید، می‌توانید پلن‌های خرید سرور مجازی ایران ایرانیکاسرور را بررسی کنید. در سرورهای چندسرویسی بهتر است برای هر برنامه Port، Reverse Proxy و Service Manager مشخصی در نظر بگیرید تا تداخل‌ها قابل‌ردیابی باشند.

تماس با پشتیبانی ایرانیکاسرور: 021-91302467

Rollback؛ اگر سرویس اشتباهی را متوقف کردیم

اگر یک systemd Service را اشتباهی Stop کرده‌اید:

sudo systemctl start SERVICE_NAME
sudo systemctl status SERVICE_NAME

اگر Container را Stop کرده‌اید:

docker start CONTAINER_NAME

اگر Docker Compose است:

docker compose up -d

اگر فقط Port برنامه جدید را تغییر داده‌اید و نتیجه مناسب نبود، Configuration قبلی را برگردانید و سرویس را Restart کنید.

اگر نمی‌دانید کدام Process را می‌توان متوقف کرد

روی سرور Production قبل از Kill کردن PID یا Stop کردن سرویس ناشناس، نقش Process را مشخص کنید. اگر برای تشخیص سرویس، systemd، Docker یا Reverse Proxy به کمک نیاز دارید، می‌توانید از خدمات کانفیگ و عیب‌یابی سرور ایرانیکاسرور استفاده کنید.

تماس با پشتیبانی ایرانیکاسرور: 021-91302467

اشتباه‌های رایج هنگام رفع Port Conflict

  • اجرای مستقیم kill -9 بدون شناسایی Process؛
  • بررسی فقط TCP در حالی که برنامه UDP است؛
  • نادیده گرفتن IPv6؛
  • Kill کردن docker-proxy به‌جای مدیریت Container؛
  • Stop کردن دیتابیس فقط برای آزاد کردن Port؛
  • Kill کردن Processای که systemd یا PM2 فوراً دوباره اجرا می‌کند؛
  • اشتباه گرفتن Connectionهای TIME_WAIT با Listener فعال؛
  • تغییر Port برنامه بدون اصلاح Reverse Proxy یا Firewall؛
  • استفاده هم‌زمان Nginx و Apache روی یک IP و Port بدون معماری مشخص؛
  • تغییر تصادفی تنظیمات Kernel برای حل یک Port Conflict ساده.

سؤالات متداول

خطای Address already in use دقیقاً یعنی چه؟

یعنی برنامه هنگام Bind کردن Socket نتوانسته آدرس موردنظر را بگیرد؛ یکی از علت‌های اصلی این است که آدرس و Port قبلاً در اختیار Socket دیگری قرار دارد. در Linux این وضعیت معمولاً با خطای EADDRINUSE گزارش می‌شود.

چطور بفهمیم چه برنامه‌ای Port را اشغال کرده است؟

برای TCP می‌توانید از sudo ss -ltnp استفاده کنید. برای یک Port مشخص نیز lsof -i :PORT یا fuser PORT/tcp کمک می‌کند PID و Process مسئول را پیدا کنید.

آیا برای آزاد کردن Port باید kill -9 بزنیم؟

خیر. ابتدا باید مشخص کنید Process چیست. اگر systemd Service یا Container است، همان Service Manager را برای Stop کردن استفاده کنید. برای Process مستقل نیز ابتدا SIGTERM معمولی مناسب‌تر است و SIGKILL باید آخرین راه باشد.

چرا بعد از Kill کردن Process دوباره همان Port اشغال می‌شود؟

احتمالاً Process تحت مدیریت systemd، Docker Restart Policy، PM2، Supervisor یا سیستم مشابهی است و به‌صورت خودکار دوباره اجرا می‌شود. باید Manager اصلی را پیدا کنید.

خطای port is already allocated در Docker را چطور رفع کنیم؟

ابتدا با docker ps --filter publish=PORT بررسی کنید کدام Container همان Host Port را Publish کرده است. سپس Container قبلی را در صورت عدم نیاز Stop کنید یا Host Port سرویس جدید را تغییر دهید.

آیا دو برنامه می‌توانند از یک Port استفاده کنند؟

دو برنامه عادی نمی‌توانند هم‌زمان همان ترکیب IP، Protocol و Port را بدون تنظیمات Socket خاص در اختیار بگیرند. اگر روی IPهای متفاوت Bind شوند، در بعضی سناریوها استفاده از شماره Port یکسان ممکن است.

چرا ss روی Port چیزی نشان نمی‌دهد اما برنامه EADDRINUSE می‌دهد؟

ممکن است Protocol اشتباه را بررسی کرده باشید، Listener روی IPv6 باشد، Unix Socket درگیر باشد، Permission کافی برای مشاهده Process نداشته باشید یا شرایط Race بین Start و Stop برنامه وجود داشته باشد.

آیا TIME_WAIT همان Port اشغال‌شده است؟

نه لزوماً. TIME_WAIT یک وضعیت Connection TCP است و با یک Listener فعال فرق دارد. برای پیدا کردن Process اشغال‌کننده Port ابتدا Socketهای Listening را با ss -ltnp بررسی کنید.

جمع‌بندی: برای رفع Address Already in Use ابتدا Port را کورکورانه آزاد نکنید؛ Process صاحب آن را شناسایی کنید. ss ابزار اصلی برای دیدن Listenerهاست و lsof و fuser می‌توانند PID را تأیید کنند. بعد مشخص کنید Process متعلق به systemd، Docker، PM2 یا برنامه مستقل است. اگر سرویس فعلی لازم است، Port برنامه جدید را تغییر دهید؛ اگر سرویس قدیمی اضافی است، آن را از Manager اصلی به‌صورت Graceful متوقف کنید.

اشتراک‌گذاری مقاله
گفت‌وگو درباره آموزش

دیدگاه‌ها (۰)

هنوز دیدگاهی ثبت نشده است.

دیدگاه یا سؤال خود را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *