commons-net 用户手册

简介

Commons-Net库参考Apache Commons Net,基于仓颉语言实现了许多基本Internet协议的客户端,旨在简化网络协议的实现,允许开发者在仓颉应用程序中轻松地集成网络功能,特别是在需要进行远程操作、数据传输和协议交互的场景中。

基本用法

FTP

FTP协议(File Transfer Protocol,文件传输协议)是一种在网络中进行文件传输的广泛使用的标准协议。作为网络通信中的基础工具,FTP允许用户通过客户端软件与服务器进行交互,实现文件的上传、下载和其他文件操作。

连接登录

连接到FTP服务器,可以使用以下方式连接并登录:

let client = FTPClient()
client.connect(server)  // 连接目标服务器
client.login(user, password) 

FTP工作模式

FTP协议支持两种工作模式:主动模式和被动模式,默认为主动模式。可以使用以下操作进入指定模式:

// 进入被动模式
client.enterLocalPassiveMode()  

// 进入主动模式
client.enterLocalActiveMode()

当需要传输数据时,主动模式下服务端连接到客户端的端口,而被动模式下,客户端连接到服务端的端口。

获取相关信息

使用'listFiles'方法或者'listDirectories'方法获取当前目录下或者指定路径的文件或者文件夹,可以使用以下方式获取相关信息:

// 获取指定路径下的文件
client.listFiles(path)  

// 获取指定路径下的文件夹
client.listDirectories(path) 

// 获取指定路径下包含的文件名列表
client.listNames(path) 

当'path'为空时,则获取当前工作目录下的信息。

文件的相关操作

ftp协议允许客户进行客户端与服务器之间的交互,实现了文件的上传、下载、删除和重命名等,具体操作如下:

// 上传本地文件到远端
client.storeFile(remote, local) 

// 下载远端文件到本地
client.retrieveFile(remote, local) 

// 删除指定文件
client.deleteFile(file) 

// 文件重命名
client.rename(name, newname)

文件夹的相关操作

实现了文件夹的相关操作,如创建、删除、切换等,具体操作如下:

// 输出当前工作目录的路径
client.printWorkingDirectory()

// 创建文件夹
client.makeDirectory(dir)

// 更改工作目录
client.changeWorkingDirectory(path)

// 切换到当前工作目录的父目录
client.changeToParentDirectory()

// 删除文件夹
client.removeDirectory(dir)

SMTP

SMTP用于发送邮件信息。

连接登录

AuthenticatingSMTPClient 是支持身份认证的SMTP客户端。 可以使用以下方式连接服务器并进行认证:

let client = AuthenticatingSMTPClient(true) // true-隐式模式/false-显式模式
client.connect(server, 465)  // 目标服务器,端口号
client.elogin()
client.auth(SMTP_AUTH_METHOD.LOGIN, user, pass) // 使用用户名密码进行认证

发送邮件

  • 发送简单信息

使用sendSimpleMessage可以快捷设置发件人和收件人,并发送指定的信息(需包含信息头和信息体)。

let header = SimpleSMTPHeader("from","to","subject")
client.sendSimpleMessage(sender, recipient, header.toString() + "message content")
  • 发送信息

发送之前,需要设置发送者和接收者。

client.setSender(sender)
client.addRecipient(recipient)

使用sendMessageData发送信息。

let header = SimpleSMTPHeader("from","to","subject")
try (writer = client.sendMessageData().getOrThrow()) {
    writer.write(header.toString())
    writer.write("test smtp")
}
client.completePendingCommand()

sendMessageData将返回一个 DotTerminatedMessageWriter 用于向服务器写入内容。需要先写入信息头,然后写入信息体。需要在写完后关闭writer或者使用try with resource。 关闭返回的writer后,需要调用completePendingCommand()接收来自服务器的完成回复,并验证响应码是否成功。

退出

使用logout方法从服务器退出登录。

client.logout()

TELNET

TELNET可以登录到远程服务器并执行命令。

创建TelnetClient并连接

let telnet = TelnetClient()
telnet.connect(server)

获取输入流以处理服务器输出

spawn {
    let reader = StringReader(telnet.getInputStream().getOrThrow())
    try {
        while (let Some(ch) <- reader.read()) {
            Console.stdOut.write(ch)
        }
    } catch (e: Exception) {
        e.printStackTrace()
    } finally {
        println("disconnect")
        telnet.disconnect()
    }
}

获取输出流以向服务器写入数据

let out = telnet.getOutputStream().getOrThrow()
while (let Some(line) <- Console.stdIn.readln()) {
    if (telnet.isConnected()) {
        out.write("${line}\r\n".toArray())
        out.flush()
    } else {
        break
    }
}
telnet.disconnect()

NNTP

连接NNTP服务器

let client = NNTPClient()
client.connect(nntpServer)

获取新闻组列表

let newgroups = client.listNewsgroups()

选择指定的新闻组

let newsgroup = NewsgroupInfo() // 用于保存返回的新闻组的信息
client.selectNewsgroup(groupName, newsgroup)

选择指定的文章

client.selectNextArticle() // 下一个
client.selectPreviousArticle() // 上一个
client.selectArticle(newgroup.getFirstArticle()) //指定的

读取文章信息

let articleReader = client.retrieveArticle().getOrThrow()
while(let Some(line) <- articleReader.readln()) {
    println(line)
}
articleReader.close()

通过retrieveArticle可以得到一个reader,从中可以读取文章信息。如果只需要读取文章头或文章体信息,可以使用retrieveArticleHeaderretrieveArticleBody方法。

IMAP

IMAP用于从服务器获取邮件。

连接登录

let client = IMAPClient()
client.connect(server)
client.login(user, pass)

获取信息

// 列出邮箱(文件夹)
client.list("", "*")

// 查看邮箱
client.examine("mailbox")

// 选择收件箱
client.select("inbox")

// 获取信息状态(信息范围)
client.status("inbox", STATUS_DATA_ITEMS.MESSAGES)

// 获取指定信息内容
client.fetch("1", "(INTERNALDATE BODY.PEEK[])")

以上方法获取的响应通过getReplyStrings方法获取,返回结果为一个数组,每个元素为服务器响应的一行内容。如果要处理多行内容的响应,可以通过setChunkListener在每收到一个响应块时进行处理。

POP3

pop3协议主要用于支持使用客户端远程管理在服务器上的电子邮件。

连接登录

let client = POP3Client()
client.connect(server)
client.login(user, pass)

获取信息

// 获取当前POP3客户端状态
client.getState()

// 列出所有邮件信息
client.listMessages()

// 从POP3服务器删除指定邮件
client.deleteMessage(messageId)

// 查看指定邮件内容
client.retrieveMessage(messageId)

'listMessages'方法会返回一个'POP3MessageInfo'实例的数组,按邮件在邮箱中的显示顺序表示所有邮件,每个实例包含一条邮件的编号、以字节为单位的大小以及唯一标识符。

DAYTIME

DaytimeTCPClient

使用DaytimeTCPClient获取服务器时间可以参考以下流程:

1.创建Daytime协议客户端

2.连接Daytime服务器

3.获取服务器时间

4.断开连接

//创建
var testdaytimetcp: DaytimeTCPClient = DaytimeTCPClient()
//链接
testdaytimetcp.connect("127.0.0.1")
//获取服务器时间
var tcptime = testdaytimetcp.getTime()
println("Tcp Daytime get time:\n" + tcptime)
//断开连接
testdaytimetcp.disconnect()

DaytimeUDPClient

使用DaytimeTCPClient获取时间可以参考以下流程:

1.创建Daytime协议客户端

2.设置超时时间

3.打开套接字

3.获取指定服务器上时间

4.断开连接

//创建
var testudp: DaytimeUDPClient = DaytimeUDPClient()
//设置超时时间
testudp.setDefaultTimeout(Duration.second * 5)
//打开套接字
testudp.open()
//获取服务器处时间
var getdata = testudp.getTime("127.0.0.1")
println("Udp Daytime get time:\n" + getdata)
//断开连接
testudp.close()

ECHO

EchoTCPClient

EchoTCPClient为Echo 协议的 TCP 客户端,它的使用可以参考以下流程:

1.创建EchoTCPClient对象

2.连接echo服务器

3.获取客户端使用的套接字

4.通过所使用套接字发送数据

5.通过所使用套接字接受数据

6.断开连接

//创建
var testechotcp: EchoTCPClient = EchoTCPClient()
//与echo服务器连接
testechotcp.connect("192.168.3.97") 
//获取客户端使用的套接字
var localsocket: TcpSocket = testechotcp.getSocket().getOrThrow()
var senddata: Array<Byte> = "hello world!test tcp echo".toArray()
//发送数据
localsocket.write(senddata)
var getdata: Array<Byte> = Array<Byte>(128, repeat: 0)
//接受数据
var number: Int64 = localsocket.read(getdata)
//断开连接
testechotcp.disconnect()

EchoUDPClient

EchoUDPClient为Echo 协议的 TCP 客户端,它的使用可以参考以下流程:

1.创建EchoUDPClient协议客户端

2.设置超时时间

3.打开套接字

4.向echo服务器发送数据

5.接收echo服务器返回数据并获取返回数据大小

6.获取缓冲区中存储的返回数据

7.断开连接

//创建 
var testudp: EchoUDPClient = EchoUDPClient()
//设置超时时间
testudp.setDefaultTimeout(Duration.second * 5)
//打开套接字
testudp.open()
var senddata: Array<Byte> = "test udp echo".toArray()
//向echo服务器发送数据
testudp.echosend(senddata, "192.168.3.97")
var getdata: Array<Byte> = Array<Byte>(32, repeat: 0)
//接受数据并获取数据大小
var number = testudp.receive(getdata)
//获取存储在缓冲区中的接受数据
getdata = testudp.getreceivedata()
//断开连接
testudp.close()

NTP

NTPUDPClient用于发送时间请求,与时间服务器交换时间,从而计算出自己时间的延迟,调整与服务器同步。NTPUDPClient的使用可以参考如下流程:

1.创建NTPUDPClient对象

2.从指定ntp服务器获取时间包

3.根据时间包获取服务器时间的某种形式的字符串

4.计算偏移和延迟的时间

5.获取调整本地时钟以匹配远程时钟所需的时钟偏移量

6.获取往返时间延迟

7.断开连接

//创建
var ntpclient: NTPUDPClient = NTPUDPClient()
//与指定ntp服务器连接并获取时间包
var time: TimeInfo = ntpclient.getTime("ntp.aliyun.com")

//根据时间包获取服务器时间的某种形式的字符串。
//其中time.getReturnTime()会得到获得传回的时间值,为从UnixEpoch开始经过的毫秒数
//可以通过DateTime.fromUnixTimeStamp(Duration.millisecond * time.getReturnTime())将其转换为DateTime形式。
//之后加上DateTime.now() - DateTime.nowUTC()用于转化为当地时区的时间,
//最后用Data.toString方法转为自定义形式的字符串。
var returntime: String = (DateTime.fromUnixTimeStamp(Duration.millisecond * time.getReturnTime()) +(DateTime.now() - DateTime.nowUTC())).toString("www, MMM dd YYYY HH:mm:ss.S")
println("ReturnTime=" + returntime)

//计算偏移和延迟的时间
time.computeDetails()
//获取调整本地时钟以匹配远程时钟所需的时钟偏移量
var offset_time : Int64 = time.getOffset()
//获取往返时间延迟
var delay_time : Int64 = time.getDelay()
//断开连接
ntpclient.close()

TFTP

TFTPClient类实现通过 TFTP 接收和发送文件。

接收文件

使用TFTPClient从tftp服务器接收文件可以参考如下流程:

1.在接受文件将要放置的位置创建一个空文件

2.创建TFTPClient对象

3.打开连接

4.从Tftp服务器中获取指定文件放置在空文件处

5.断开连接

var filepath: Path = Path("./doc/test/server1.txt")
if (File.exists(filepath)) {
  File.delete(filepath)
}
var receivefile: File = File(filepath, OpenOption.Create(true))
//创建
var testtftp: TFTPClient = TFTPClient()
//打开连接
testtftp.open()
//接收文件
var receivenumber = testtftp.receiveFile("server1.txt", 0, receivefile, server_ip)
//断开连接
testtftp.close()

发送文件

使用TFTPClient发送文件到tftp服务器可以参考如下流程:

1.获取指定路径处的文件

2.创建TFTPClient对象

3.打开连接

4.将文件发送至服务器,并命名为指定名字

5.断开连接

 //获取指定路径下的文件
 var testfile: File = File("./doc/test/server1.txt", OpenOption.Open(true, true))
 //创建
 var testtftp: TFTPClient = TFTPClient()
 //打开连接
 testtftp.open()
 //发送文件
 testtftp.sendFile("sendtest.txt", 0, testfile, server_ip)
 //断开连接
 testtftp.close()

TIME

TimeTCPClient

TimeTCPClient 类是基于 TCP 的时间协议客户端实现,使用其检索服务器时间可以参考如下流程:

1.创建TimeTCPClient对象

2.连接服务器

3.获取服务器时间对应的DateTime对象

4.获取服务器时间

5.断开连接

//创建
var testTimetcp: TimeTCPClient = TimeTCPClient()
//连接诶服务器
testTimetcp.connect("127.0.0.1")
//获取服务器时间对应的DateTime对象,并且已转换为本地时区
var tcpdatetime = testTimetcp.getDateTime()
//获取服务器时间。时间表示为自1900年1月1日00:00(午夜)GMT以来的秒数
var tcptime = testTimetcp.getTime()
//断开连接
testTimetcp.disconnect()

TimeUDPClient

TimeUDPClient 类是基于 UDP 的时间协议客户端实现,使用其检索服务器时间可以参考如下流程:

1.创建TimeUDPClient对象

2.设置超时时间

3.打开连接

4.获取服务器时间对应的DateTime对象

5.获取服务器时间

6.断开连接

 //创建
 var testudp: TimeUDPClient = TimeUDPClient()
 //设置超时时间
 testudp.setDefaultTimeout(Duration.second * 5)
 //打开连接诶
 testudp.open()
 //获取服务器时间对应的DateTime对象,并且已转换为本地时区
 var getdata = testudp.getTime("127.0.0.1")
 //获取服务器时间。时间表示为自1900年1月1日00:00(午夜)GMT以来的秒数
 var getdatetime = testudp.getDateTime("127.0.0.1")
 //断开连接
 testudp.close()