Golang中支持会话恢复的FTPS有哪些可用包

Golang中支持会话恢复的FTPS有哪些可用包 我们正在尝试连接并上传文件到支持会话重用的FTPS服务器。 不幸的是,我们未能找到任何支持此功能的包。

您有什么建议吗?

示例:

package main
import (
“crypto/tls”
“fmt”
“log”
“os”
“time”
“github.com/secsy/goftp”
)
func main() {
ftpServer := “” //ftp server ftps.abc.com
ftpUser := “”     // ftp user name
ftpPassword := “”  //ft password
ftpFolder := “” //Folder in ftpserver where file needs to be uploaded.
ftpFile := “”     //File location which needs to be uploaded.
start := time.Now()
var (
tlsConfig *tls.Config = &tls.Config{
InsecureSkipVerify: true,
ClientAuth:         tls.RequestClientCert,
}
)
config := goftp.Config{
User:               ftpUser,
Password:           ftpPassword,
ConnectionsPerHost: 10,
Timeout:            30 * time.Second,
Logger:             os.Stderr,
TLSConfig:          tlsConfig,
//DisableEPSV:        true,
//ActiveTransfers:    true,
//TLSMode:           goftp.TLSImplicit,
}
client, err := goftp.DialConfig(config, ftpServer)
if err != nil {
panic(err)
}
var file *os.File
file, err = os.Open(ftpFile)
defer file.Close()
if err != nil {
panic(err)
}
//b, _ := ioutil.ReadFile(ftpFile)
err = client.Store(fmt.Sprintf(ftpFolder, “/”, ftpFile), file)
if err != nil {
fmt.Println(err)
}
elapsed := time.Since(start)
log.Printf(“Process took %s”, elapsed)
os.Exit(0)
}

更多关于Golang中支持会话恢复的FTPS有哪些可用包的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang中支持会话恢复的FTPS有哪些可用包的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go语言中,支持FTPS会话恢复的包确实有限。以下是几个可用的选项:

  1. github.com/jlaffaye/ftp:这是最常用的FTP包,支持TLS/SSL,但会话恢复需要手动实现。
  2. github.com/secsy/goftp:您已经在使用,它支持TLS,但会话恢复同样需要额外处理。

对于会话恢复,您需要在代码中实现重连和状态恢复的逻辑。以下是一个使用jlaffaye/ftp包实现会话恢复的示例:

package main

import (
    "crypto/tls"
    "fmt"
    "log"
    "net"
    "time"
    "github.com/jlaffaye/ftp"
)

type FTPSClient struct {
    conn     *ftp.ServerConn
    host     string
    username string
    password string
    tlsConfig *tls.Config
}

func NewFTPSClient(host, username, password string) *FTPSClient {
    return &FTPSClient{
        host:     host,
        username: username,
        password: password,
        tlsConfig: &tls.Config{
            InsecureSkipVerify: true, // 仅测试使用,生产环境应配置正确证书
        },
    }
}

func (c *FTPSClient) Connect() error {
    dialer := &net.Dialer{Timeout: 30 * time.Second}
    conn, err := ftp.Dial(c.host, ftp.DialWithDialer(dialer), ftp.DialWithTLS(c.tlsConfig))
    if err != nil {
        return err
    }
    
    err = conn.Login(c.username, c.password)
    if err != nil {
        return err
    }
    
    c.conn = conn
    return nil
}

func (c *FTPSClient) Reconnect() error {
    if c.conn != nil {
        c.conn.Quit()
    }
    return c.Connect()
}

func (c *FTPSClient) UploadFile(remotePath string, localPath string) error {
    // 尝试上传,如果失败则重连重试
    err := c.upload(remotePath, localPath)
    if err != nil {
        log.Println("Upload failed, reconnecting...")
        if reconnectErr := c.Reconnect(); reconnectErr != nil {
            return fmt.Errorf("reconnect failed: %v", reconnectErr)
        }
        // 重试上传
        return c.upload(remotePath, localPath)
    }
    return nil
}

func (c *FTPSClient) upload(remotePath string, localPath string) error {
    file, err := os.Open(localPath)
    if err != nil {
        return err
    }
    defer file.Close()
    
    return c.conn.Stor(remotePath, file)
}

func main() {
    client := NewFTPSClient("ftps.example.com:21", "username", "password")
    
    // 初始连接
    if err := client.Connect(); err != nil {
        log.Fatal(err)
    }
    defer client.conn.Quit()
    
    // 上传文件,支持会话恢复
    if err := client.UploadFile("/remote/path/file.txt", "./local/file.txt"); err != nil {
        log.Fatal(err)
    }
    
    log.Println("File uploaded successfully")
}

对于secsy/goftp包,您可以类似地实现重连逻辑:

package main

import (
    "crypto/tls"
    "fmt"
    "log"
    "time"
    "github.com/secsy/goftp"
)

func createClient(server, user, pass string) (*goftp.Client, error) {
    config := goftp.Config{
        User:     user,
        Password: pass,
        Timeout:  30 * time.Second,
        TLSConfig: &tls.Config{
            InsecureSkipVerify: true,
        },
        TLSMode: goftp.TLSExplicit,
    }
    
    return goftp.DialConfig(config, server)
}

func uploadWithRetry(client *goftp.Client, remotePath, localPath string, maxRetries int) error {
    var err error
    for i := 0; i < maxRetries; i++ {
        file, openErr := os.Open(localPath)
        if openErr != nil {
            return openErr
        }
        
        err = client.Store(remotePath, file)
        file.Close()
        
        if err == nil {
            return nil
        }
        
        log.Printf("Upload attempt %d failed: %v", i+1, err)
        
        // 重新创建客户端
        if i < maxRetries-1 {
            time.Sleep(2 * time.Second)
            client, err = createClient("ftps.example.com:21", "user", "pass")
            if err != nil {
                return fmt.Errorf("reconnect failed: %v", err)
            }
        }
    }
    return err
}

func main() {
    client, err := createClient("ftps.example.com:21", "user", "pass")
    if err != nil {
        log.Fatal(err)
    }
    
    err = uploadWithRetry(client, "/remote/file.txt", "./local/file.txt", 3)
    if err != nil {
        log.Fatal(err)
    }
    
    log.Println("File uploaded successfully")
}

这些示例展示了如何在Go中实现FTPS的会话恢复功能。需要注意的是,这些包本身不提供自动会话恢复,需要您在应用层实现重连和重试逻辑。

回到顶部