Address already in use
這個(gè)提示,想必大家遇到過(guò),怎么能快速找到問(wèn)題并解決呢?下面有幾種姿勢(shì)可以了解一下.
在對(duì)網(wǎng)絡(luò)連接或特定于應(yīng)用程序的問(wèn)題進(jìn)行故障排除時(shí),首先要檢查的事情之一應(yīng)該是系統(tǒng)上實(shí)際使用了哪些端口,以及哪個(gè)應(yīng)用程序正在偵聽(tīng)特定的端口。
本文介紹了如何使用netstat
,ss
和lsof
命令找出哪些服務(wù)正在偵聽(tīng)哪些端口。該說(shuō)明適用于所有基于Linux和Unix的操作系統(tǒng),例如macOS。
什么是監(jiān)聽(tīng)端口
網(wǎng)絡(luò)端口由其編號(hào),關(guān)聯(lián)的IP地址和通信協(xié)議(例如TCP或UDP)的類型標(biāo)識(shí)。
偵聽(tīng)端口是應(yīng)用程序或進(jìn)程在其上偵聽(tīng)的網(wǎng)絡(luò)端口,充當(dāng)通信端點(diǎn)。
每個(gè)監(jiān)聽(tīng)端口都可以使用防火墻打開(kāi)或關(guān)閉(過(guò)濾)。一般而言,開(kāi)放端口是一個(gè)網(wǎng)絡(luò)端口,它接受來(lái)自遠(yuǎn)程位置的傳入數(shù)據(jù)包。
你不能讓兩個(gè)服務(wù)監(jiān)聽(tīng)同一IP地址上的同一端口。
例如,如果你正在運(yùn)行一個(gè)監(jiān)聽(tīng)端口80
和443
的Apache Web服務(wù)器,并且嘗試安裝Nginx ,則后者將無(wú)法啟動(dòng),因?yàn)镠TTP和HTTPS端口是已經(jīng)在使用中。
用netstat
檢查監(jiān)聽(tīng)端口
netstat
是一個(gè)命令行工具,可以提供有關(guān)網(wǎng)絡(luò)連接的信息。
要列出所有正在偵聽(tīng)的TCP或UDP端口,包括使用端口的服務(wù)和套接字狀態(tài),請(qǐng)使用以下命令:
sudo netstat -tunlp
此命令中使用的選項(xiàng)具有以下含義:
-n
-顯示數(shù)字地址而不是解析主機(jī)。-p
-顯示偵聽(tīng)器進(jìn)程的PID和名稱。僅當(dāng)你以root用戶或 sudo 用戶身份運(yùn)行命令時(shí),才會(huì)顯示此信息。
輸出將如下所示:
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0:22 0:* LISTEN 445/sshd
tcp 0 0 0:25 0:* LISTEN 929/master
tcp6 0 0 :::3306 ::* LISTEN 534/mysqld
tcp6 0 0 :::80 :::* LISTEN 515/apache2
tcp6 0 0 :::22 :::* LISTEN 445/sshd
tcp6 0 0 :::25 :::* LISTEN 929/master
tcp6 0 0 :::33060 :::* LISTEN 534/mysqld
udp 0 0 0:68 0:* 966/dhclient
在我們的案例中,重要的幾列是:
Local Address
-進(jìn)程偵聽(tīng)的IP地址和端口號(hào)。PID/Program name
-PID和進(jìn)程名稱。
如果要過(guò)濾結(jié)果,請(qǐng)使用 grep命令。例如,要查找在TCP端口22上偵聽(tīng)的進(jìn)程,你可以輸入:
sudo netstat -tnlp | grep :22
輸出顯示此計(jì)算機(jī)上的端口22被SSH服務(wù)器使用:
tcp 0 0 0:22 0:* LISTEN 445/sshd
tcp6 0 0 :::22 :::* LISTEN 445/sshd
如果輸出為空,則表示端口上沒(méi)有監(jiān)聽(tīng)。
你也可以根據(jù)條件過(guò)濾列表,例如PID,協(xié)議,狀態(tài)等。
netstat
已過(guò)時(shí),被ss
和 ip
取代,但它仍然是檢查網(wǎng)絡(luò)連接的最常用命令。
用ss
檢查監(jiān)聽(tīng)端口
ss
是新的netstat
。它缺少netstat
的某些功能,但是公開(kāi)了更多的TCP狀態(tài),并且速度稍快。命令選項(xiàng)基本相同,因此從netstat
到ss
的轉(zhuǎn)換并不困難。
要使用ss
獲取所有監(jiān)聽(tīng)端口的列表,請(qǐng)輸入:
sudo ss -tunlp
輸出與netstat
報(bào)告的輸出幾乎相同:
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 0:22 0:* users:(('sshd',pid=445,fd=3))
LISTEN 0 100 0:25 0:* users:(('master',pid=929,fd=13))
LISTEN 0 128 *:3306 *:* users:(('mysqld',pid=534,fd=30))
LISTEN 0 128 *:80 *:* users:(('apache2',pid=765,fd=4),('apache2',pid=764,fd=4),('apache2',pid=515,fd=4))
LISTEN 0 128 [::]:22 [::]:* users:(('sshd',pid=445,fd=4))
LISTEN 0 100 [::]:25 [::]:* users:(('master',pid=929,fd=14))
LISTEN 0 70 *:33060 *:* users:(('mysqld',pid=534,fd=33))
使用lsof
檢查監(jiān)聽(tīng)端口
lsof
是功能強(qiáng)大的命令行應(yīng)用程序,可提供有關(guān)進(jìn)程打開(kāi)的文件的信息。
在Linux中,所有內(nèi)容都是文件。你可以將套接字視為寫(xiě)入網(wǎng)絡(luò)的文件。
要獲取具有lsof
的所有偵聽(tīng)TCP端口的列表,請(qǐng)輸入:
sudo lsof -nP -iTCP -sTCP:LISTEN
使用的選項(xiàng)如下:
-n
-不要將端口號(hào)轉(zhuǎn)換為端口名稱。-p
-不解析主機(jī)名,顯示數(shù)字地址。
-iTCP -sTCP:LISTEN
-僅顯示TCP狀態(tài)為L(zhǎng)ISTEN的網(wǎng)絡(luò)文件。
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 445 root 3u IPv4 16434 0t0 TCP *:22 (LISTEN)
sshd 445 root 4u IPv6 16445 0t0 TCP *:22 (LISTEN)
apache2 515 root 4u IPv6 16590 0t0 TCP *:80 (LISTEN)
mysqld 534 mysql 30u IPv6 17636 0t0 TCP *:3306 (LISTEN)
mysqld 534 mysql 33u IPv6 19973 0t0 TCP *:33060 (LISTEN)
apache2 764 www-data 4u IPv6 16590 0t0 TCP *:80 (LISTEN)
apache2 765 www-data 4u IPv6 16590 0t0 TCP *:80 (LISTEN)
master 929 root 13u IPv4 19637 0t0 TCP *:25 (LISTEN)
master 929 root 14u IPv6 19638 0t0 TCP *:25 (LISTEN)
大多數(shù)輸出列名稱都是不言自明的:
COMMAND
,PID
,USER
-運(yùn)行與端口關(guān)聯(lián)的程序的名稱,PID和用戶。
要查找正在偵聽(tīng)特定端口(例如端口3306
)的進(jìn)程,可以使用:
sudo lsof -nP -iTCP:3306 -sTCP:LISTEN
輸出顯示MySQL服務(wù)器使用端口3306
:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
mysqld 534 mysql 30u IPv6 17636 0t0 TCP *:3306 (LISTEN)