Java寫黑軟-連接埠掃描器篇__Java

來源:互聯網
上載者:User

Java寫黑軟-連接埠掃描器篇
海嘯天鳴(Ansty)
上次我們用Java寫了一個“檔案最後修改時間編輯器”的小黑軟,現在我們來用Java來寫我們平時經常用的連接埠掃描器。這次為了方便和避免GUI編程的麻煩,我們就直接做成命令列下面的工具,用參數來啟動它。我們姑且把它命名為“Java版簡單連接埠掃描工具”,因為本文只是提供Java寫黑軟的思路,許多演算法最佳化和功能附加不在本文的討論之列,使用的也是單線程。
程式介面:



程式原理:
利用java.net.Socket類來建立socket串連,如果無法與指定的IP和連接埠建立串連,將會拋出IOException。我們用try-catch對這個IOException這個異常進行捕獲,以判斷是否成功與指定的IP連接埠建立串連。如果成功建立了串連,說明指定IP的指定連接埠已經開放;如果程式拋出了一個IOException異常被我們捕獲,則說明指定的IP沒有開放指定的連接埠。掃描指定連接埠段則是利用迴圈不斷與伺服器的指定連接埠進行串連,供我們判斷是否開放。

我一直堅信,世界上的所有問題只要有了明確的演算法,我們就一定能用程式語言來實現它,無論什麼語言。現在,我們有了原理就等於有了演算法,你說我們除了技術以外還缺什麼。只缺動手了。

因為我們要從程式啟動的參數中獲得伺服器位址、開始端點口、終止連接埠的資訊,所以我們就要用到下面這段代碼:
ip = args[0]; //獲得我們指定的伺服器位址
startPort = Integer.parseInt(args[1]); //獲得開始端點口號,因為args[]是String類型,所以要強制轉換成int類型。
endPort = Integer.parseInt(args[2]); //獲得終止連接埠號碼,同上
在得到連接埠和建立socket之前一定要判斷連接埠的合法性,因為連接埠的範圍是在1~65535,如果我們去建立範圍外連接埠的串連是沒必要的,而且是不可行的。既然是開始端點口和終止連接埠,那麼就要有個大小順序問題,就是判斷它們的大小。 Copy code

if(startPort<1||startPort>65535||endPort<1||endPort>65535){    //檢查連接埠是否在合法範圍1~65535
System.out.printf("連接埠範圍必須在1~65535以內!");
return;
}else if(startPort>endPort){ //比較開始端點口和終止連接埠
System.out.println("連接埠輸入有誤!/n開始端點口必須小於終止連接埠");
return;
}


建立與伺服器指定連接埠的串連,這裡就要用到java.net.Socket類了,首先我們來看看它的構造方法:
Socket() 通過系統預設類型的 SocketImpl 建立未串連通訊端
Socket(InetAddress address, int port) 建立一個流通訊端並將其串連到指定 IP 位址的指定連接埠號碼。
Socket(InetAddress address, int port, InetAddress localAddr, int localPort) 建立一個通訊端並將其串連到指定遠程連接埠上的指定遠程地址。
Socket(Proxy proxy) 根據不管其他設定如何都應使用的指定代理類型(如果有),建立一個未串連的通訊端。
Socket(SocketImpl impl) 建立帶有使用者指定的 SocketImpl 的未串連 Socket。
Socket(String host, int port) 建立一個流通訊端並將其串連到指定主機上的指定連接埠號碼。
Socket(String host, int port, InetAddress localAddr, int localPort) 建立一個通訊端並將其串連到指定遠程主機上的指定遠程連接埠。
可以看到,我們有很多中構造方法,我們現在只需要關心第二種構造方法Socket(InetAddress address, int port),因為我們並不需要與伺服器運行在連接埠的服務進行互動,所以我們只要建立串連,然後關閉串連即可。即:
Socket s = new Socket(address,port);
我們在建立串連之前,首先要把ip轉換成InetAddress類型,不是說String類型不能用,是為了能減少出現更多異常的可能。
static InetAddress getByName(String host) 在給定主機名稱的情況下確定主機的 IP 位址。這是靜態方法,直接InetAddress.getByName()就行了。
Copy code

try{
InetAddress address = InetAddress.getByName(ip); //轉換類型
}catch(UnknownHostException e){
System.out.println("無法找到 "+ ip);
return;
}


下面是我們的核心演算法了
迴圈指定連接埠段的所有連接埠,對所有連接埠建立串連。串連成功後我們就算完成了當前迴圈的任務,然後就調用close()方法關閉串連。因為在Socket s = new Socket(address,nport)執行的時候,如果成功建立串連,就不會執行到catch裡面,就能執行到下面result.add(“”+nport)語句;如果不能串連上去就會拋出一個異常被我們捕獲,程式就會運行到catch裡面,執行catch裡面的語句;最後繼續下一個迴圈。
Copy code

for(int nport=startPort;nport<=endPort;nport++){    //從開始端點口到終止連接埠進行迴圈
try{
System.out.print("Scanning "+nport); //列印掃描進度
Socket s=new Socket(address,nport); //建立串連
s.close(); //關閉串連
result.add(""+nport); //將開啟的連接埠添加到ArrayList result裡面
System.out.println(" : open"); //列印狀態
}catch(IOException e){
System.out.println(":close"); //列印狀態
}
}


列印結果,因為我們用到了ArrayList來儲存掃描結果,Java裡面沒有C語言意義上的指標,所以我們在訪問ArrayList裡面的元素要用到ListIterator。
ListIterator li = result.listIterator(); //獲得ArrayList的ListIterator
while(li.hasNext()){ // 如果li裡面有元素
System.out.println(li.next().toString()+"/tOpen"); //列印出指向的元素,同時將指向下一個元素
}
好了,現在我們就已經把主要功能的程式碼介紹完了,相信讀者看完以後能用Java編寫自己的Java版黑軟了。正如我前文說的,本文只提供一種思路。如果朋友有興趣,可以自己在本文的基礎上實現多線程、擴充一些有用的功能,把GUI介面做出來,或者做成仿SuperScan就更強大了。本人在黑防論壇的ID是Ansty,大家對本文有問題可以到論壇裡M我

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.