程序猿的福音 - Apache Commons Net

此文是系列文章第八篇,前幾篇請(qǐng)點(diǎn)擊鏈接查看

程序猿的福音 - Apache Commons簡介

程序員的福音 - Apache Commons Lang

程序員的福音 - Apache Commons IO

程序員的福音 - Apache Commons Codec

程序員的福音 - Apache Commons Compress

程序員的福音 - Apache Commons Exec

程序員的福音 - Apache Commons Email

Apache Commons Net 庫實(shí)現(xiàn)了許多基本Internet協(xié)議的客戶端。庫的目的是提供基本的協(xié)議訪問,而不是更高級(jí)別的抽象。

Commons-Net 最初是一個(gè)名為 NetComponents 的商業(yè) Java 庫,最初由 ORO,Inc. 在 Java 早期開發(fā)的。在 1998 發(fā)布了 1.3.8 版本后,源代碼被捐贈(zèng)給 Apache 軟件基金會(huì),并在 APACHE 許可證下可用。從那時(shí)起,許多程序員為 Commons-Net 的持續(xù)發(fā)展做出了貢獻(xiàn)。當(dāng)前版本的編號(hào)方案與舊版本無關(guān)。也就是說,Commons net 1.0 成功地取代了 NetComponents 1.3.8。

Commons-Net 目前最新版本是 3.8.0,最低要求 Java7 以上。

maven坐標(biāo)如下:

<dependency>
    <groupId>commons-net</groupId>
    <artifactId>commons-net</artifactId>
    <version>3.8.0</version>
</dependency>

包結(jié)構(gòu)如下:

org.apache.commons.net
org.apache.commons.net.bsd
org.apache.commons.net.chargen
org.apache.commons.net.daytime
org.apache.commons.net.discard
org.apache.commons.net.echo
org.apache.commons.net.finger
org.apache.commons.net.ftp
org.apache.commons.net.imap
org.apache.commons.net.io
org.apache.commons.net.nntp
org.apache.commons.net.ntp
org.apache.commons.net.pop3
org.apache.commons.net.smtp
org.apache.commons.net.telnet
org.apache.commons.net.tftp
org.apache.commons.net.time
org.apache.commons.net.util
org.apache.commons.net.whois

下面簡單介紹一下它的結(jié)構(gòu)和用法。

01. 概覽

Commons-Net 的核心是實(shí)現(xiàn)了各種網(wǎng)絡(luò)協(xié)議的Client類,其中兩個(gè)核心抽象類 SocketClientDatagramSocketClient ,SocketClient 是所有TCP實(shí)現(xiàn)的基類, DatagramSocketClient 是所有UDP實(shí)現(xiàn)的基類。其中支持的協(xié)議如下(S結(jié)尾就是使用 SSL/TLS 做通信加密,類似 http 和 https 的關(guān)系):

FTP/FTPS:FTP(File Transfer Protocol,文件傳輸協(xié)議)是 TCP/IP 協(xié)議組中的協(xié)議之一。FTP協(xié)議包括兩個(gè)組成部分,其一為FTP服務(wù)器,其二為FTP客戶端。其中FTP服務(wù)器用來存儲(chǔ)文件,用戶可以使用FTP客戶端通過FTP協(xié)議訪問位于FTP服務(wù)器上的資源。在開發(fā)網(wǎng)站的時(shí)候,通常利用FTP協(xié)議把網(wǎng)頁或程序傳到Web服務(wù)器上。此外,由于FTP傳輸效率非常高,在網(wǎng)絡(luò)上傳輸大的文件時(shí),一般也采用該協(xié)議。實(shí)現(xiàn)該協(xié)議的類是FTPClient/FTPSClient

FTP over HTTP (experimental):以http協(xié)議實(shí)現(xiàn)FTP的功能。由于FTP工作在被動(dòng)模式時(shí)不僅需要將21作為FTP的控制(命令)端口,還要將20作為FTP的數(shù)據(jù)端口,因此在配置防火墻時(shí)比較麻煩,不如用http協(xié)議傳輸文件。因此可以利用原有的網(wǎng)站結(jié)合Alias的方法加目錄訪問控制來實(shí)現(xiàn)。實(shí)現(xiàn)該協(xié)議的類是FTPHTTPClient

NNTP:網(wǎng)絡(luò)新聞組傳輸協(xié)議(Network News Transfer Protocol)是一個(gè)主要用于閱讀和張貼新聞文章到Usenet上的Internet應(yīng)用協(xié)議,也負(fù)責(zé)新聞在服務(wù)器間的傳送。實(shí)現(xiàn)該協(xié)議的類是NNTPClient

SMTP(S):SMTP(Simple Mail Transfer Protocol)是一種提供可靠且有效的電子郵件傳輸?shù)膮f(xié)議。SMTP是建立在FTP文件傳輸服務(wù)上的一種郵件服務(wù),主要用于系統(tǒng)之間的郵件信息傳遞,并提供有關(guān)來信的通知。實(shí)現(xiàn)該協(xié)議的類是SMTPClient****/****SMTPSClient

POP3(S):POP3,全名為“Post Office Protocol - Version 3”,即“郵局協(xié)議版本3”。POP3協(xié)議允許電子郵件客戶端下載服務(wù)器上的郵件,但是在客戶端的操作(如移動(dòng)郵件、標(biāo)記已讀等),不會(huì)反饋到服務(wù)器上。實(shí)現(xiàn)該協(xié)議的類是POP3Client/POP3SClient

IMAP(S):IMAP(Internet Message Access Protocol)以前稱作交互郵件訪問協(xié)議(Interactive Mail Access Protocol),是一個(gè)應(yīng)用層協(xié)議。它的主要作用是郵件客戶端可以通過這種協(xié)議從郵件服務(wù)器上獲取郵件的信息,下載郵件等。IMAP提供webmail 與電子郵件客戶端之間的雙向通信,客戶端的操作都會(huì)反饋到服務(wù)器上,對(duì)郵件進(jìn)行的操作,服務(wù)器上的郵件也會(huì)做相應(yīng)的動(dòng)作。實(shí)現(xiàn)該協(xié)議的類是IMAPClient/IMAPSClient

Telnet:Telnet協(xié)議是TCP/IP協(xié)議族中的一員,是Internet遠(yuǎn)程登錄服務(wù)的標(biāo)準(zhǔn)協(xié)議和主要方式。它為用戶提供了在本地計(jì)算機(jī)上完成遠(yuǎn)程主機(jī)工作的能力。在終端使用者的電腦上使用telnet程序,用它連接到服務(wù)器。終端使用者可以在telnet程序中輸入命令,這些命令會(huì)在服務(wù)器上運(yùn)行,就像直接在服務(wù)器的控制臺(tái)上輸入一樣。Telnet是常用的遠(yuǎn)程控制Web服務(wù)器的方法。實(shí)現(xiàn)該協(xié)議的類是TelnetClient

TFTP:TFTP(Trivial File Transfer Protocol,簡單文件傳輸協(xié)議)是TCP/IP協(xié)議族中的一個(gè)用來在客戶機(jī)與服務(wù)器之間進(jìn)行簡單文件傳輸?shù)膮f(xié)議,提供不復(fù)雜、開銷不大的文件傳輸服務(wù)。端口號(hào)為69。實(shí)現(xiàn)該協(xié)議的類是TFTPClient

Finger:顯示有關(guān)運(yùn)行 Finger 服務(wù)或 Daemon 的指定遠(yuǎn)程計(jì)算機(jī)(通常是運(yùn)行 UNIX 的計(jì)算機(jī))上用戶的信息。該遠(yuǎn)程計(jì)算機(jī)指定顯示用戶信息的格式和輸出。實(shí)現(xiàn)該協(xié)議的類是FingerClient

Whois:whois 是用來查詢域名的IP以及所有者等信息的傳輸協(xié)議。簡單說,whois就是一個(gè)用來查詢域名是否已經(jīng)被注冊(cè),以及注冊(cè)域名的詳細(xì)信息的數(shù)據(jù)庫(如域名所有人、域名注冊(cè)商)。早期的whois查詢多以命令行接口存在,但是現(xiàn)在出現(xiàn)了一些網(wǎng)頁的線上查詢工具,其仍依賴whois協(xié)議。命令行工具仍然被系統(tǒng)管理員廣泛使用。whois通常使用TCP協(xié)議43端口。每個(gè)域名/IP的whois信息由對(duì)應(yīng)的管理機(jī)構(gòu)保存。實(shí)現(xiàn)該協(xié)議的類是WhoisClient

rexec/rcmd/rlogin:是一組Unix命令,遠(yuǎn)程執(zhí)行,遠(yuǎn)程登錄,起源于BSD系統(tǒng)。實(shí)現(xiàn)該協(xié)議的類是RExecClient/RCommandClient/RLoginClient****

Time (rdate) / DaytimeDAYTIME協(xié)議是基于TCP的應(yīng)用,是一種有用的調(diào)試工具,它的作用是返回當(dāng)前時(shí)間和日期,格式是字符串格式。Time時(shí)間協(xié)議(英語:TIME protocol)是一個(gè)在RFC 868內(nèi)定義的網(wǎng)絡(luò)傳輸協(xié)議。它用作提供機(jī)器可讀的日期時(shí)間信息。實(shí)現(xiàn)該協(xié)議的類是TimeTCPClient/TimeUDPClient,DaytimeTCPClient/DaytimeUDPClient

Echo:echo是一個(gè)計(jì)算機(jī)命令,它可以基于TCP協(xié)議,也可以基于UDP協(xié)議,服務(wù)器在端口7檢測(cè)有無消息。是路由也是網(wǎng)絡(luò)中最常用的數(shù)據(jù)包,可以通過發(fā)送echo包知道當(dāng)前的連接節(jié)點(diǎn)有那些路徑,并且通過往返時(shí)間能得出路徑長度。實(shí)現(xiàn)該協(xié)議的類是EchoTCPClient/EchoUDPClient

Discard:拋棄協(xié)議,作用就是接收到什么拋棄什么,它對(duì)調(diào)試網(wǎng)絡(luò)狀態(tài)的一定的用處。實(shí)現(xiàn)該協(xié)議的類是****DiscardTCPClient/DiscardUDPClient

NTP/SNTP:NTP服務(wù)器【Network Time Protocol(NTP)】是用來使計(jì)算機(jī)時(shí)間同步化的一種協(xié)議,它可以使計(jì)算機(jī)對(duì)其服務(wù)器或時(shí)鐘源(如石英鐘,GPS等等)做同步化。實(shí)現(xiàn)該協(xié)議的類是****NTPUDPClient

客戶端類圖如下:

圖片
圖片

02. 工具方法

Commons-Net 還提供了一些網(wǎng)絡(luò)相關(guān)的工具類,簡化我們的一些網(wǎng)絡(luò)處理,主要有以下幾個(gè)

SubnetUtils:在給定網(wǎng)絡(luò)地址和子網(wǎng)掩碼的情況下執(zhí)行一些子網(wǎng)計(jì)算

TrustManagerUtils:TrustManager 工具類

KeyManagerUtils:KeyManager 工具類

SSLContextUtils:SSLContext 工具類

下面看看代碼示例

1. SSL相關(guān)

Java API 寫法:

// 使用jdk原生獲取SSLContext
String key = "c:/client.jks";
String password = "123456"; // key密碼
KeyStore keyStore = KeyStore.getInstance("JKS");  //創(chuàng)建一個(gè)keystore來管理密鑰庫
keyStore.load(new FileInputStream(key), password.toCharArray());
//創(chuàng)建jkd密鑰訪問庫
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(keyStore);
KeyManager[] kms = kmf.getKeyManagers();
TrustManager[] tms = tmf.getTrustManagers();
SSLContext ctx = SSLContext.getInstance("TLSv1"); // 支持SSLv2, SSLv3, TLSv1, TLSv1.1, SSLv2Hello
ctx.init(kms, tms, null);

Commons Net 寫法:

// 使用commons-net相關(guān)工具類寫法
String key = "c:/client.jks";
String password = "123456"; // key密碼
File keyFile = new File(key);
KeyManager km = KeyManagerUtils.createClientKeyManager(keyFile, password);
TrustManager tm = TrustManagerUtils.getDefaultTrustManager(keyStore);
SSLContext ctx2 = SSLContextUtils.createSSLContext("TLSv1", km, tm);

2. 子網(wǎng)工具類

// 以下為兩種初始化subnet工具類的方式
// 1. 使用IP和子網(wǎng)掩碼
SubnetUtils subnet = new SubnetUtils("192.168.1.113", "255.255.255.0");
// 2. 使用CIDR格式地址
// SubnetUtils subnet = new SubnetUtils("192.168.1.113/24");

// 獲取網(wǎng)絡(luò)各種參數(shù)
SubnetUtils.SubnetInfo si = subnet.getInfo();
// 獲取IP地址
si.getAddress(); // 192.168.1.113
// 獲取網(wǎng)絡(luò)地址(IP地址和子網(wǎng)掩碼進(jìn)行與運(yùn)算,結(jié)果是網(wǎng)絡(luò)地址,即主機(jī)號(hào)全0是網(wǎng)絡(luò)地址)
si.getNetworkAddress(); // 192.168.1.0
// 獲取廣播地址(專門用于同時(shí)向網(wǎng)絡(luò)中所有工作站進(jìn)行發(fā)送的一個(gè)地址)
si.getBroadcastAddress(); // 192.168.1.255
// 獲取子網(wǎng)下的起始地址
si.getLowAddress(); // 192.168.1.1
// 獲取子網(wǎng)下的終止地址
si.getHighAddress(); // 192.168.1.254
// 獲取上一個(gè)地址
si.getPreviousAddress(); // 192.168.1.112
// 獲取下一個(gè)地址
si.getNextAddress(); // 192.168.1.114
// 獲取子網(wǎng)掩碼
si.getNetmask(); // 255.255.255.0
// 獲取CIDR格式的網(wǎng)絡(luò)地址
si.getCidrSignature(); // 192.168.1.113/24
// 獲取子網(wǎng)最大IP個(gè)數(shù)
si.getAddressCountLong(); // 254
// 獲取所有IP地址數(shù)組
si.getAllAddresses(); // [192.168.1.1, ..., 192.168.1.254]

03. 網(wǎng)絡(luò)客戶端

Commons-Net 提供的網(wǎng)絡(luò)客戶端非常多,此處只列舉幾個(gè)簡單的做下示例:

1. WhoisClient

// 基于TCP協(xié)議
WhoisClient whoisClient = new WhoisClient();
try {
    // 基于TCP使用connect
    whoisClient.connect(WhoisClient.DEFAULT_HOST);
    String host = whoisClient.query("baidu.com");
    System.out.println(host);
} finally {
    // 基于TCP需要主動(dòng)斷開連接
    whoisClient.disconnect();
}

2. TimeUDPClient

// 基于UDP協(xié)議
TimeUDPClient timeClient = new TimeUDPClient();
timeClient.setDefaultTimeout(3000);
InetAddress addr = InetAddress.getByName("time.nist.gov");
// UDP使用open
timeClient.open();
Date d = timeClient.getDate(addr);
System.out.println(DateFormatUtils.format(d, "yyyy-MM-dd HH:mm:ss.SSS"));
// UDP使用close關(guān)閉連接
timeClient.close();

其他簡單協(xié)議就不做示例了。復(fù)雜協(xié)議(如FTP)由于支持功能較多,篇幅原因也不做代碼示例了,感興趣的可以到 https://mirrors.tuna.tsinghua.edu.cn/apache//commons/net/source/commons-net-3.8.0-src.zip 這里下載源碼查看其中的Example。

04. 總結(jié)

Commons Net 做為網(wǎng)絡(luò)工具包,實(shí)現(xiàn)了很多網(wǎng)絡(luò)協(xié)議的客戶端,如果有相關(guān)需求可以考慮使用,也可以基于 Net 的基礎(chǔ)自行擴(kuò)展。

后續(xù)章節(jié)我將繼續(xù)給大家介紹 commons 中其他好用的工具類庫,期待你的關(guān)注。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容