FTP 简介
FTP
是 File Transfer Protocol
的缩写,文件传输协议的简称。FTP
是仅基于 TCP
的服务,不支持 UDP
。 它使用两个端口,一个数据端口和一个命令端口(也可叫做控制端口),通常来说这两个端口是 21-命令端口
和 20-数据端口
。
FTP
主要有两种模式:主动模式(PORT
)/被动模式(PASV
),还有两种模式 EPRT
/EPSV
(Extended Port/Pasv
) 是针对IPv6对FTP再次进行扩展。
目前大部分的 FTP
客户端都是默认以被动模式来连接 FTP
服务器的。这里的主动/被动是对于 FTP
服务器来说的,是服务器打开端口,被动
的等待客户端连接,还是服务端主动
去连接客户端打开的端口。
FileZilla 工具
常用的 FTP
工具有很多,这里简单介绍一下 FileZilla
。FileZilla 中文网,接下来会用它来在本地搭建一个 FTP
服务,用于测试。
服务端
windows
下载地址:windows FileZilla_Server_1.3.0_win64-setup.exe
下载好后安装即可,现建立用户名为 test
,密码为 1234546
的用户,并配置映射文件夹,为之后的测试做准备。
客户端
windows
绿色版下载地址:windows FileZilla_3.58.0_win32.zip
可以使用该客户端来验证我们的服务是否已正确。
go FTP
客户端
GitHub
上有许多库可以使用,这里主要介绍一下 FTP
的客户端库的使用:github.com/jlaffaye/ftp
示例
基础示例
import (
"bytes"
"commonTest/utils"
"fmt"
"github.com/jlaffaye/ftp"
)
func t1() {
c, err := ftp.Dial("127.0.0.1:21")
utils.CheckErr(err)
defer c.Quit()
// 可以重复连接,创建不同的实例
//c1, err := ftp.Dial("127.0.0.1:21")
//utils.CheckErr(err)
//defer c1.Quit()
err = c.Login("test", "123456")
utils.CheckErr(err)
// 新建文件
//reader := bytes.NewReader([]byte("12356546"))
//err = c.Stor("1.txt", reader)
//utils.CheckErr(err)
// 创建文件夹,可以嵌套 dir1/dir11
err = c.MakeDir("dir1")
utils.CheckErr(err)
fmt.Println("创建文件夹成功")
// 进入文件夹,可以嵌套 dir1/dir11
err = c.ChangeDir("dir1")
utils.CheckErr(err)
fmt.Println("进入文件夹成功")
// 新建文件
reader := bytes.NewReader([]byte("12356546"))
err = c.Stor("1.txt", reader)
utils.CheckErr(err)
fmt.Println("创建文件成功")
dir, err := c.CurrentDir()
utils.CheckErr(err)
fmt.Println("current dir: ", dir)
// 返回上一级
err = c.ChangeDirToParent()
utils.CheckErr(err)
fmt.Println(c.CurrentDir())
//entries, err := c.List("/")
//utils.CheckErr(err)
}
确保文件夹已存在
func EnsureFtpDirExist(c *ftp.ServerConn, dir string) error {
// 这里不能直接 MakeDir,有权限问题
_, err := c.List(dir)
if err != nil {
if er := c.MakeDir(dir); er != nil {
if er.Error() == "550 Directory with same name already exists." {
return nil
}
return er
}
}
return nil
}
总结
FTP
主要用于文件的传输,其只支持TCP
,不支持UDP
协议。- 分为主动/被动模式,主动/被动是相对于服务端来说的。
- FileZilla 是比较成熟的
FTP
产品,建议使用。 - github.com/jlaffaye/ftp:
go
实现的FTP
客户端,目前只支持被动模式连接服务器。有人提了issue
希望支持主动模式,作者回答说:
目前基本上所有的
FTP
服务都支持被动模式连接,没有发现主动模式的使用场景,暂且没有加的打算。
另外提一下,上述的测试代码都在我的 Gitee/GoTest 仓库 ,ftp
目录下的文件中,这个项目主要是日常学习的一些记录与测试,感兴趣的可以看看。