此文是系列文章第八篇,前几篇请点击链接查看
程序员的福音 - Apache Commons Compress
Apache Commons Net 库实现了许多基本Internet协议的客户端。库的目的是提供基本的协议访问,而不是更高级别的抽象。
Commons-Net 最初是一个名为 NetComponents 的商业 Java 库,最初由 ORO,Inc. 在 Java 早期开发的。在 1998 发布了 1.3.8 版本后,源代码被捐赠给 Apache 软件基金会,并在 APACHE 许可证下可用。从那时起,许多程序员为 Commons-Net 的持续发展做出了贡献。当前版本的编号方案与旧版本无关。也就是说,Commons net 1.0 成功地取代了 NetComponents 1.3.8。
Commons-Net 目前最新版本是 3.8.0,最低要求 Java7 以上。
maven坐标如下:
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.8.0</version>
</dependency>
包结构如下:
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
下面简单介绍一下它的结构和用法。
01. 概览
Commons-Net 的核心是实现了各种网络协议的Client类,其中两个核心抽象类 SocketClient 和 DatagramSocketClient ,SocketClient 是所有TCP实现的基类, DatagramSocketClient 是所有UDP实现的基类。其中支持的协议如下(S结尾就是使用 SSL/TLS 做通信加密,类似 http 和 https 的关系):
FTP/FTPS:FTP(File Transfer Protocol,文件传输协议)是 TCP/IP 协议组中的协议之一。FTP协议包括两个组成部分,其一为FTP服务器,其二为FTP客户端。其中FTP服务器用来存储文件,用户可以使用FTP客户端通过FTP协议访问位于FTP服务器上的资源。在开发网站的时候,通常利用FTP协议把网页或程序传到Web服务器上。此外,由于FTP传输效率非常高,在网络上传输大的文件时,一般也采用该协议。实现该协议的类是FTPClient/FTPSClient
FTP over HTTP (experimental):以http协议实现FTP的功能。由于FTP工作在被动模式时不仅需要将21作为FTP的控制(命令)端口,还要将20作为FTP的数据端口,因此在配置防火墙时比较麻烦,不如用http协议传输文件。因此可以利用原有的网站结合Alias的方法加目录访问控制来实现。实现该协议的类是FTPHTTPClient
NNTP:网络新闻组传输协议(Network News Transfer Protocol)是一个主要用于阅读和张贴新闻文章到Usenet上的Internet应用协议,也负责新闻在服务器间的传送。实现该协议的类是NNTPClient
SMTP(S):SMTP(Simple Mail Transfer Protocol)是一种提供可靠且有效的电子邮件传输的协议。SMTP是建立在FTP文件传输服务上的一种邮件服务,主要用于系统之间的邮件信息传递,并提供有关来信的通知。实现该协议的类是SMTPClient****/****SMTPSClient
POP3(S):POP3,全名为“Post Office Protocol - Version 3”,即“邮局协议版本3”。POP3协议允许电子邮件客户端下载服务器上的邮件,但是在客户端的操作(如移动邮件、标记已读等),不会反馈到服务器上。实现该协议的类是POP3Client/POP3SClient
IMAP(S):IMAP(Internet Message Access Protocol)以前称作交互邮件访问协议(Interactive Mail Access Protocol),是一个应用层协议。它的主要作用是邮件客户端可以通过这种协议从邮件服务器上获取邮件的信息,下载邮件等。IMAP提供webmail 与电子邮件客户端之间的双向通信,客户端的操作都会反馈到服务器上,对邮件进行的操作,服务器上的邮件也会做相应的动作。实现该协议的类是IMAPClient/IMAPSClient
Telnet:Telnet协议是TCP/IP协议族中的一员,是Internet远程登录服务的标准协议和主要方式。它为用户提供了在本地计算机上完成远程主机工作的能力。在终端使用者的电脑上使用telnet程序,用它连接到服务器。终端使用者可以在telnet程序中输入命令,这些命令会在服务器上运行,就像直接在服务器的控制台上输入一样。Telnet是常用的远程控制Web服务器的方法。实现该协议的类是TelnetClient
TFTP:TFTP(Trivial File Transfer Protocol,简单文件传输协议)是TCP/IP协议族中的一个用来在客户机与服务器之间进行简单文件传输的协议,提供不复杂、开销不大的文件传输服务。端口号为69。实现该协议的类是TFTPClient
Finger:显示有关运行 Finger 服务或 Daemon 的指定远程计算机(通常是运行 UNIX 的计算机)上用户的信息。该远程计算机指定显示用户信息的格式和输出。实现该协议的类是FingerClient
Whois:whois 是用来查询域名的IP以及所有者等信息的传输协议。简单说,whois就是一个用来查询域名是否已经被注册,以及注册域名的详细信息的数据库(如域名所有人、域名注册商)。早期的whois查询多以命令行接口存在,但是现在出现了一些网页的线上查询工具,其仍依赖whois协议。命令行工具仍然被系统管理员广泛使用。whois通常使用TCP协议43端口。每个域名/IP的whois信息由对应的管理机构保存。实现该协议的类是WhoisClient
rexec/rcmd/rlogin:是一组Unix命令,远程执行,远程登录,起源于BSD系统。实现该协议的类是RExecClient/RCommandClient/RLoginClient****
Time (rdate) / Daytime:DAYTIME协议是基于TCP的应用,是一种有用的调试工具,它的作用是返回当前时间和日期,格式是字符串格式。Time时间协议(英语:TIME protocol)是一个在RFC 868内定义的网络传输协议。它用作提供机器可读的日期时间信息。实现该协议的类是TimeTCPClient/TimeUDPClient,DaytimeTCPClient/DaytimeUDPClient
Echo:echo是一个计算机命令,它可以基于TCP协议,也可以基于UDP协议,服务器在端口7检测有无消息。是路由也是网络中最常用的数据包,可以通过发送echo包知道当前的连接节点有那些路径,并且通过往返时间能得出路径长度。实现该协议的类是EchoTCPClient/EchoUDPClient
Discard:抛弃协议,作用就是接收到什么抛弃什么,它对调试网络状态的一定的用处。实现该协议的类是****DiscardTCPClient/DiscardUDPClient
NTP/SNTP:NTP服务器【Network Time Protocol(NTP)】是用来使计算机时间同步化的一种协议,它可以使计算机对其服务器或时钟源(如石英钟,GPS等等)做同步化。实现该协议的类是****NTPUDPClient
客户端类图如下:
图片 图片02. 工具方法
Commons-Net 还提供了一些网络相关的工具类,简化我们的一些网络处理,主要有以下几个
SubnetUtils:在给定网络地址和子网掩码的情况下执行一些子网计算
TrustManagerUtils:TrustManager 工具类
KeyManagerUtils:KeyManager 工具类
SSLContextUtils:SSLContext 工具类
下面看看代码示例
1. SSL相关
Java API 写法:
// 使用jdk原生获取SSLContext
String key = "c:/client.jks";
String password = "123456"; // key密码
KeyStore keyStore = KeyStore.getInstance("JKS"); //创建一个keystore来管理密钥库
keyStore.load(new FileInputStream(key), password.toCharArray());
//创建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相关工具类写法
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. 子网工具类
// 以下为两种初始化subnet工具类的方式
// 1. 使用IP和子网掩码
SubnetUtils subnet = new SubnetUtils("192.168.1.113", "255.255.255.0");
// 2. 使用CIDR格式地址
// SubnetUtils subnet = new SubnetUtils("192.168.1.113/24");
// 获取网络各种参数
SubnetUtils.SubnetInfo si = subnet.getInfo();
// 获取IP地址
si.getAddress(); // 192.168.1.113
// 获取网络地址(IP地址和子网掩码进行与运算,结果是网络地址,即主机号全0是网络地址)
si.getNetworkAddress(); // 192.168.1.0
// 获取广播地址(专门用于同时向网络中所有工作站进行发送的一个地址)
si.getBroadcastAddress(); // 192.168.1.255
// 获取子网下的起始地址
si.getLowAddress(); // 192.168.1.1
// 获取子网下的终止地址
si.getHighAddress(); // 192.168.1.254
// 获取上一个地址
si.getPreviousAddress(); // 192.168.1.112
// 获取下一个地址
si.getNextAddress(); // 192.168.1.114
// 获取子网掩码
si.getNetmask(); // 255.255.255.0
// 获取CIDR格式的网络地址
si.getCidrSignature(); // 192.168.1.113/24
// 获取子网最大IP个数
si.getAddressCountLong(); // 254
// 获取所有IP地址数组
si.getAllAddresses(); // [192.168.1.1, ..., 192.168.1.254]
03. 网络客户端
Commons-Net 提供的网络客户端非常多,此处只列举几个简单的做下示例:
1. WhoisClient
// 基于TCP协议
WhoisClient whoisClient = new WhoisClient();
try {
// 基于TCP使用connect
whoisClient.connect(WhoisClient.DEFAULT_HOST);
String host = whoisClient.query("baidu.com");
System.out.println(host);
} finally {
// 基于TCP需要主动断开连接
whoisClient.disconnect();
}
2. TimeUDPClient
// 基于UDP协议
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关闭连接
timeClient.close();
其他简单协议就不做示例了。复杂协议(如FTP)由于支持功能较多,篇幅原因也不做代码示例了,感兴趣的可以到 https://mirrors.tuna.tsinghua.edu.cn/apache//commons/net/source/commons-net-3.8.0-src.zip 这里下载源码查看其中的Example。
04. 总结
Commons Net 做为网络工具包,实现了很多网络协议的客户端,如果有相关需求可以考虑使用,也可以基于 Net 的基础自行扩展。
后续章节我将继续给大家介绍 commons 中其他好用的工具类库,期待你的关注。
网友评论