準確的說,他是一個網絡鏈接端口查看器,能夠根據進程查端口,也能夠根據端口查進程。期初是因在使用Fiddler的時候發現沒法啓動,提示端口被佔用,可是由不知道用什麼方法才能找到是哪一個程序佔用的Fiddler的端口,遂使用命令行的netstat命令配合find命令才找到,遂想寫這樣一個相似的工具幫助咱們速度定位相似端口問題的所在。html
PS:可預見不少人會說爲何不用360網絡連接查看器,或是其餘相似軟件,功能更強大界面更美觀巴拉巴拉…?git
答:由於我喜歡bat批處理,我喜歡命令行,喜歡能用幾句命令搞定的事就不用一個別的軟件來搞,更重要的是享受編寫代碼這其中的過程。github
主要功能就兩個:編程
一、查詢某個進程都在使用哪些端口號,包含同進程名的全部實例,以及他們分別所佔用的TCP和UDP端口。windows
二、查看某個端口被哪一個進程使用,包括遠程IP和本地IP,以及TCP和UDP的全部端口服務器
程序界面:網絡
本程序返回值使用的windows命令行下的netstat命令。函數
Netstat,在Internet RFC標準中,Netstat的定義是: Netstat是在內核中訪問網絡及相關信息的程序,它能提供TCP鏈接,TCP和UDP監聽,進程內存管理的相關報告。工具
具體的關於netstat命令的用法能夠參見:netstat百度百科,WIKI,如何用netstat命令查看端口占用問題等測試
PID(ProcessID)操做系統裏指進程ID號。操做系統裏每打開一個程序都會建立一個進程ID,即PID。
PID就是各進程的身份標識,程序一運行系統就會自動分配給進程一個獨一無二的PID。進程停止後PID被系統回收,可能會被繼續分配給新運行的程序。
PID一列表明瞭各進程的進程ID,也就是說,PID就是各進程的身份標識。
鏈接狀態。在原模式中沒有狀態,在用戶數據報協議中也常常沒有狀態,因而狀態列能夠空出來。如有狀態,一般取值爲:
LISTEN
偵聽來自遠方的TCP端口的鏈接請求
SYN-SENT
在發送鏈接請求後等待匹配的鏈接請求
SYN-RECEIVED
在收到和發送一個鏈接請求後等待對方對鏈接請求的確
ESTABLISHED
表明一個打開的鏈接
FIN-WAIT-1
等待遠程TCP鏈接中斷請求,或先前的鏈接中斷請求的確認
FIN-WAIT-2
從遠程TCP等待鏈接中斷請求
CLOSE-WAIT
等待從本地用戶發來的鏈接中斷請求
CLOSING
等待遠程TCP對鏈接中斷的確認
LAST-ACK
等待原來的發向遠程TCP的鏈接中斷請求的確認
TIME-WAIT
等待足夠的時間以確保遠程TCP接收到鏈接中斷請求的確認CLOSED
沒有任何鏈接狀態
簡單的講,本地地址即當前這個連接到你本機通訊的IP地址和端口,外部地址即當前這個連接到的遠程服務器地址和端口。
固然本地和外部地址都有多是本地地址,通常端口不同而已。一個典型的應用就是代理服務軟件
具體的能夠參見:端口百科 中相關地址的解釋,或是參見:NAT概念中的四類地址概念,也有助於理解。
這裏咱們查詢Fiddler.exe所佔用的端口號,在主界面選擇1,回車。再輸入Fiddler回車
能夠看到紅框內,Fiddler佔用了本地IPv4和IPv6的8888端口,而且一直處於監聽(LISTENING)狀態。
注意:最後一行的[::]表示IPv6的全部地址,等同於IPv4的0.0.0.0地址
此地址在不一樣環境有不一樣名稱,若在路由表中他表示默認路由。在網絡編程中,若監聽此地址的端口,則可至關於同時監聽本地迴環地址127.0.0.1以及localhost地址以及本機全部網卡的本地地址(如192.168.1.100)的端口。
反之,若只監聽當前網卡本地地址192.168.1.100的端口,則使用127.0.0.1地址就訪問不到
關於0.0.0.0和127.0.0.1的區別能夠參考:紅黑,文庫,stackoverflow,以及 知乎的討論等
好了扯遠了,繼續說bat用法,看到本地全零地址,以及監聽狀態,就能夠判斷此程序Fiddler在佔用8888端口,此時如有其餘程序如IIS,湯姆貓之類的程序要啓動同端口就會報錯了。
再看看QQ的佔用狀況:
能夠看到當前有兩個進程叫QQ.exe,他們的分別的連接狀況及TCP、UDP連接如圖所示。
這裏咱們依舊測試Fiddler的8888端口,這裏輸入2回車,輸入端口號8888回車,查看結果:
能夠看到8888端口在IPv4和IPv6上都由Fiddler.exe在佔用(監聽)
幫助信息:
注意:若沒法使用或查詢無響應,請使用管理員權限啓用本批處理,方法能夠參照我以前寫的文章:如何建立管理員權限的CMD命令提示符窗口
源碼已經託管至Github:
https://github.com/xxcanghai/cnblogsFiles/blob/master/NetstatFilter網絡鏈接查看器.bat
或是直接複製下述全部代碼保存到.bat文件後,直接運行便可。
批處理代碼:
::NetstatFilter網絡鏈接查看器 @小小滄海 xxcanghai.cnblogs.com By:2015年6月29日 @echo off :start title NetstatFilter By:xxcanghai SETLOCAL ENABLEEXTENSIONS&SETLOCAL ENABLEDELAYEDEXPANSION cls ::######config###### set PCENAME= set PID= set PORT= ::inner config set ERRORCODE=0 :menu cls&echo ----------NetstatFilter---------- echo [1]查詢指定進程名使用的端口號 echo [2]查看指定端口被哪一個進程使用 echo [3]幫助信息 echo. set /p=請輸入對應數字:<nul set select=3&set /p select= if /i "%select%"=="q" exit /b if /i "%select%"=="exit" exit /b if "%select%"=="1" goto :menuitem1 if "%select%"=="2" goto :menuitem2 if "%select%"=="3" goto :help cls&goto :menu :menuitem1 set /p=請輸入要查詢的進程名稱:<nul set PCENAME=&set /p PCENAME= if /i "%PCENAME%"=="q" goto :menu if "%PCENAME%"=="" goto :menuitem1 if "%PCENAME:.=%"=="%PCENAME%" set PCENAME=%PCENAME%.exe call :getpid "%PCENAME%" PID echo Process:%PCENAME%,PID:%PID% call :getnetbypid "%PID%" echo @1END&pause>nul&goto start :menuitem2 set /p=請輸入要查詢的端口號:<nul set PORT=&set/p PORT= if /i "%PORT%"=="q" goto :menu if "%PORT%"=="" goto :menuitem2 call :getnetbyport "%PORT%" echo @2END&pause>nul&goto start :help cls echo ┏━━━━━━━━━━━━━━NetstatFilter ━━━━━━━━━━━━━━━━┓ echo ┃ netstat命令的輔助工具 @小小滄海 xxcanghai.cnblogs.com ┃ echo ┃ ┃ echo ┃1.可查詢某個進程在使用哪些端口,包含同名進程的多個實例及全部TCP和UDP端口 ┃ echo ┃2.可查詢指定端口正在被哪些進程使用,以及本地/遠程IP端口和當前鏈接狀態 ┃ echo ┃ =注意= ┃ echo ┃※1.若沒法使用或查詢無反應請用管理員權限執行本批處理,方法參照上述博客文章┃ echo ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ echo 按任意鍵返回主菜單&pause>nul&goto start ::#####get pid by process##### ::[tasklist] example ::cmd.exe 11132 Console 1 3,000 K ::cmd.exe 8204 Console 1 2,728 K ::cmd.exe 10060 Console 1 2,996 K :getpid if not "%~1"=="" ( set PID= for /f "tokens=2 delims= " %%i in ('tasklist /fi "imagename eq %~1" /nh /fo table^|find /i "%~1"') do ( set PID=!PID!%%i, ) if "!PID!"=="" ( set ERRORCODE=101 echo [ERROR]ProcessName "%~1" is not found pause>nul&goto start ) else ( set PID=!PID:~0,-1! ) set %2=!PID! goto :eof ) ::#####get netstat by pid##### ::[netstat] example: :: Proto Local Address Foreign Address State PID :: TCP 0.0.0.0:80 0.0.0.0:0 LISTENING 4 :: UDP [::1]:50575 *:* 5108 :getnetbypid if not "%~1"=="" ( set PID=%~1 for /f "tokens=1,* delims=," %%a in ("!PID!") do ( set subpid=%%a set PID=%%b ::get TCP echo [PID-!subpid!]: for /f "delims=" %%z in ('netstat -a -n -o^|find ":"') do ( set tLine=%%z ::netstat的IPv6結果中含有%符號,%符號在call傳遞中會發生錯誤,遂將%替換爲$後再傳遞 set tLine=!tLine:%%=$! call :getNetInfo "!tLine!" tProto tLocalAdd tForeignAdd tState tPID set tLine=!tLine:$=%%! ::call使用完成後將$符號替換回%符號 if "!tPID!"=="!subpid!" ( echo !tLine! ) ) ) if not "!PID!"=="" (call %0 "!PID!") goto :eof ) ::#####get netstat by port##### :getnetbyport if not "%~1"=="" ( set PORT=%~1 for /f "tokens=1,* delims=," %%a in ("!PORT!") do ( set myport=%%a set PORT=%%b ::PORT==8888 for /f "delims=" %%z in ('netstat -a -n -o^|find /i ":!myport! "') do ( set tLine=%%z set tLine=!tLine:%%=$! call :getNetInfo "!tLine!" tProto tLocalAdd tForeignAdd tState tPID set tLine=!tLine:$=%%! echo !tLine! for /f "tokens=1 delims= " %%j in ('tasklist /nh /fi "PID eq !tPID!"') do ( echo [%%j] ) ) ) ) goto :eof echo END.&pause>nul&goto start exit ::#####FUNCTION##### :getNetInfo ::將netstat -ano的某一行分隔成不一樣的變量 ::call :getNetInfo "<netstat output line>" tProto tLocalAdd tForeignAdd tState tPID if not "%~1"=="" ( for /f "tokens=1,2,3,4,5 delims= " %%i in ("%~1") do ( set %2=%%i set %3=%%j set %4=%%k if "%%i"=="TCP" ( set %5=%%l set %6=%%m ) else ( set %5= set %6=%%l ) ) ) goto :eof ::#####FUNCTION##### :split ::%0爲函數名稱自身:split,%1爲傳過來的值,%~1爲刪除變量中的雙引號" ::在此子搜索函數中把過濾器按照/符號分割開,並取得分割後的第一個的值 ::再把分割後的剩下的值重賦予過濾器,並調用自身,直到過濾器爲空爲止,返回 set subf=%~1 for /f "tokens=1,* delims=," %%j in ("%subf%") do ( set subf=%%k ) if not "!subf!"=="" (call %0 "!subf!") goto :eof ::#####FUNCTION##### :FUN1 goto :eof